Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
304a2d2530 | ||
|
|
0bef900271 | ||
|
|
0e47879818 | ||
|
|
3ddee11275 | ||
|
|
58ad91b0f2 | ||
|
|
b75da20afa | ||
|
|
92b6937ec2 |
+1
-1
Submodule modules/frontend updated: 279b2d02a2...807c656886
+124
-55
@@ -3,11 +3,13 @@
|
||||
#
|
||||
# 动线(与 frontend/e2e/rdm-audit.spec.ts 的环境契约一一对应):
|
||||
# 1. 构建:RDM 二进制(RDM 仓 origin/main 临时 worktree,pins 物化)
|
||||
# + 基座 CLI(本 worktree modules/backend,建号用)
|
||||
# + 基座 CLI(与 RDM pin 同源;identity ensure / plain-base serve)
|
||||
# + frontend dist(本 worktree modules/frontend)
|
||||
# 2. 种子:RDM -bootstrap-admin(域管理员)→ serve 首启建基座存储 → identity ensure →
|
||||
# 基座 user bootstrap-admin(login-key 激活契约;--password 已被拒绝)→
|
||||
# redeem+设密 → API rdm.project.create×2 + rdm.ingest(主项目)
|
||||
# 2. 种子:RDM -bootstrap-admin(域管理员)→ SUPER_ADMIN_* → serve 首启建基座存储
|
||||
# (超管)→ identity ensure → 超管密码登录会话 → API rdm.project.create×2
|
||||
# → 主项目宿主会话来源(会话+一条用户消息)→ 正式命令 rdm.reqs.import /
|
||||
# rdm.ingest 等携 conversationId/anchorMessageId;
|
||||
# 普通账号(e2e-auditor 等)经超管会话 POST /api/admin/users 创建
|
||||
# 3. 验收:vite preview(dist+/api 代理)→ npx playwright test
|
||||
# 4. 收尾:停 serve/preview,保存认证/失败工件到 $E2E_OUT
|
||||
#
|
||||
@@ -17,7 +19,7 @@
|
||||
# RDM_REPO RDM 仓路径(默认 <本仓上级>/Agent-System-RDM)
|
||||
# E2E_API_PORT/E2E_UI_PORT 服务端口(默认 18791/4173)
|
||||
# E2E_OWNER/E2E_PASSWORD 登录账号(默认 e2e-auditor/E2eAudit#2026)
|
||||
# E2E_PASSWORD2 首次登录后的设密结果(默认 E2eAudit#2026b;种子命令用它)
|
||||
# E2E_PASSWORD2 首次登录后的设密结果(默认 E2eAudit#2026b;Playwright 改密门消费)
|
||||
# E2E_PROJECT_MAIN/E2E_PROJECT_ISOLATED 项目名(默认 审计演示项目/隔离检查项目)
|
||||
# E2E_OUT 工件目录(默认 .tmp/e2e/<ts>;.gitignore 已覆盖 .tmp)
|
||||
# 依赖:go、node/npm、curl;首次运行会 npx playwright install chromium。
|
||||
@@ -91,14 +93,23 @@ trap cleanup EXIT
|
||||
(cd "$RDM_WT" && go build -o "$OUT/agent-system-rdm" .) || die "rdm build failed"
|
||||
log "rdm binary: $OUT/agent-system-rdm (RDM@${RDM_SHA:0:12}, pins@${PIN_SHA_WANT:0:12})"
|
||||
|
||||
log "build base CLI (account bootstrap/activation) from the same pinned backend as the RDM binary"
|
||||
# 版本一致性:建号 CLI 必须与被测 RDM 二进制共用同一基座 pin——用 Dev 顶层
|
||||
# backend(main 最新)建号会把库迁到更高 schema,RDM pins(较旧)打不开。
|
||||
log "build base CLI (identity ensure + plain-base serve) from the same pinned backend as the RDM binary"
|
||||
# 版本一致性:基座 CLI 必须与被测 RDM 二进制共用同一基座 pin——用 Dev 顶层
|
||||
# backend(main 最新)会把库迁到更高 schema,RDM pins(较旧)打不开。
|
||||
(cd "$RDM_WT/pins/agent-system-backend" && go build -o "$OUT/agent-system" ./cmd/agent-system) \
|
||||
|| die "backend cli build failed"
|
||||
|
||||
log "build frontend dist (contracts + ui deps + bundle, via make frontend)"
|
||||
make -C "$DEV_ROOT" frontend >/dev/null || die "frontend build failed"
|
||||
# 直接构建 FE dist:不走 make frontend(其 contracts→test-worktree 要求全部
|
||||
# submodule 已物化;本脚本只需 FE+@ui 源码组合)。contracts.ts 以 FE pin 为准。
|
||||
log "build frontend dist (npm ci @ui + frontend, vite build)"
|
||||
[ -f "$DEV_ROOT/modules/ui/package.json" ] \
|
||||
|| die "modules/ui missing (need gitlink checkout for @ui alias)"
|
||||
[ -f "$DEV_ROOT/modules/frontend/package.json" ] \
|
||||
|| die "modules/frontend missing"
|
||||
(cd "$DEV_ROOT/modules/ui" && npm ci --no-fund --no-audit) >/dev/null \
|
||||
|| die "ui npm ci failed"
|
||||
(cd "$DEV_ROOT/modules/frontend" && npm ci --no-fund --no-audit && npm run build) \
|
||||
|| die "frontend build failed"
|
||||
|
||||
# ── 2. 种子 ─────────────────────────────────────────────
|
||||
DATA="$OUT/data"
|
||||
@@ -108,9 +119,13 @@ RDM="$OUT/agent-system-rdm -data $DATA"
|
||||
log "bootstrap: RDM domain admin = $OWNER"
|
||||
$RDM -bootstrap-admin "$OWNER" >/dev/null
|
||||
|
||||
# ── 凭据契约(2026-10-13 起):--password 建号被 RECOVERY_CONTRACT_REPLACED 拒绝,
|
||||
# 改走 login-key 激活:serve 首启创建基座存储 → identity ensure → 基座首位账号
|
||||
# bootstrap-admin(激活 Key 交付)→ API redeem → 设密(PASSWORD2 为登录密码)。
|
||||
# ── 凭据契约:auth on 时超管由 serve 启动期 SUPER_ADMIN_OWNER/SUPER_ADMIN_PASSWORD
|
||||
# 建立(基座已禁用 bootstrap-admin)。种子 API 会话走超管密码登录;普通账号
|
||||
# (e2e-auditor 等)经 POST /api/admin/users 创建(初始密码合成值,mustChangePassword
|
||||
# 由 Playwright 首登改密门处理)。合成测试凭据(非真实秘密)。
|
||||
: "${SUPER_ADMIN_OWNER:=e2e-superadmin}"
|
||||
: "${SUPER_ADMIN_PASSWORD:=E2eSuperAdmin#FixedTest9kQm2NpR}"
|
||||
export SUPER_ADMIN_OWNER SUPER_ADMIN_PASSWORD
|
||||
log "serve RDM at $API_BASE (auth on;首启创建基座存储)"
|
||||
start_serve() {
|
||||
"$OUT/agent-system-rdm" -data "$DATA" -addr "127.0.0.1:$API_PORT" -auth on \
|
||||
@@ -128,64 +143,115 @@ stop_serve() {
|
||||
[ -n "${API_PID:-}" ] && { kill "$API_PID" 2>/dev/null || true; wait "$API_PID" 2>/dev/null || true; API_PID=""; }
|
||||
}
|
||||
login() {
|
||||
# Seed API session uses serve-established superadmin (not E2E_OWNER).
|
||||
local i
|
||||
for i in $(seq 1 20); do
|
||||
if curl -sf -c "$JAR" -X POST "$API_BASE/api/auth/login" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{\"owner\":\"$OWNER\",\"password\":\"$PASSWORD\"}" >/dev/null; then
|
||||
-d "{\"owner\":\"$SUPER_ADMIN_OWNER\",\"password\":\"$SUPER_ADMIN_PASSWORD\"}" >/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
sleep 0.25
|
||||
done
|
||||
die "login failed"
|
||||
die "superadmin login failed"
|
||||
}
|
||||
cmd() { # cmd <id> <params-json> → payload(失败即死,种子步骤不容忍部分成功)
|
||||
local id=$1 params=${2:-{\}}
|
||||
cmd() { # cmd <id> <params-json> [extra-body-fields] → payload(失败即死,种子步骤不容忍部分成功)
|
||||
local id=$1 params=${2:-{\}} extra=${3:-}
|
||||
curl -sf -b "$JAR" -X POST "$API_BASE/api/commands/$id" \
|
||||
-H 'Content-Type: application/json' -d "{\"params\":$params}" \
|
||||
-H 'Content-Type: application/json' -d "{${extra:+$extra,}\"params\":$params}" \
|
||||
| python3 -c 'import json,sys; d=json.load(sys.stdin); r=(d or {}).get("receipt",{}); sys.exit(1) if r.get("state")=="rejected" else None; print(json.dumps(d.get("payload", d), ensure_ascii=False))' \
|
||||
|| die "command $id rejected"
|
||||
}
|
||||
admin_create_user() { # admin_create_user <owner> <password> [display-name] [isAdmin]
|
||||
# 超管会话 POST /api/admin/users;200 且 mustChangePassword:true(Playwright 首登改密)。
|
||||
# 第 4 参为 true 时任命基座管理员(admin-user-create 需「系统管理…」入口;仅超管可任命)。
|
||||
local owner=$1 password=$2 name=${3:-$1} is_admin=${4:-false} body
|
||||
body=$(curl -sf -b "$JAR" -X POST "$API_BASE/api/admin/users" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{\"owner\":\"$owner\",\"password\":\"$password\",\"profile\":{\"name\":\"$name\"},\"isAdmin\":$is_admin}") \
|
||||
|| die "admin create user $owner failed"
|
||||
printf '%s' "$body" | python3 -c 'import json,sys; d=json.load(sys.stdin); sys.exit(0 if d.get("mustChangePassword") is True else 1)' \
|
||||
|| die "admin create user $owner: expected mustChangePassword:true"
|
||||
}
|
||||
# 浏览器用例若不以改密门处理该账号(如 cockpit 的 e2e-reader),种子阶段代完 must-change。
|
||||
complete_must_change() { # complete_must_change <owner> <initial> <final>
|
||||
local owner=$1 initial=$2 final=$3 jar i
|
||||
jar="$OUT/${owner}.changepw.jar"
|
||||
for i in $(seq 1 20); do
|
||||
if curl -sf -c "$jar" -X POST "$API_BASE/api/auth/login" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{\"owner\":\"$owner\",\"password\":\"$initial\"}" >/dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 0.25
|
||||
[ "$i" = 20 ] && die "must-change login failed for $owner"
|
||||
done
|
||||
curl -sf -b "$jar" -c "$jar" -X POST "$API_BASE/api/auth/password" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{\"current\":\"$initial\",\"next\":\"$final\"}" >/dev/null \
|
||||
|| die "must-change password failed for $owner"
|
||||
}
|
||||
# 正式项目命令(rdm.reqs.*/rdm.review.*/rdm.draft.*/rdm.ingest 等,基座
|
||||
# cmdbus.RequiresProjectWorkDecision)须带已认证会话来源:conversationId 绑定宿主项目,
|
||||
# anchorMessageId 为该会话中已提交、经 RDM 来源分析放行的用户消息;裸调用被预检拒绝。
|
||||
seed_source() { # seed_source <hostProjectId>:超管在宿主项目建种子会话并提交一条来源消息
|
||||
local host=$1 body
|
||||
body=$(curl -sf -b "$JAR" -X POST "$API_BASE/api/projects/$host/conversations" \
|
||||
-H 'Content-Type: application/json' -d '{"title":"e2e seed source"}') \
|
||||
|| die "seed source conversation create failed"
|
||||
SRC_CONV=$(printf '%s' "$body" | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')
|
||||
body=$(curl -sf -b "$JAR" -X POST "$API_BASE/api/conversations/$SRC_CONV/messages" \
|
||||
-H 'Content-Type: application/json' -d '{"text":"e2e 种子:导入需求台账、入库需求语料、登记驾驶舱探针与文档职责"}') \
|
||||
|| die "seed source message failed"
|
||||
SRC_MSG=$(printf '%s' "$body" | python3 -c 'import json,sys; print(json.load(sys.stdin)["message"]["id"])')
|
||||
}
|
||||
fcmd() { # fcmd <id> <params-json>:正式项目命令,附种子会话来源
|
||||
[ -n "${SRC_MSG:-}" ] || die "formal command $1 needs seed_source first"
|
||||
cmd "$1" "$2" "\"conversationId\":\"$SRC_CONV\",\"anchorMessageId\":\"$SRC_MSG\""
|
||||
}
|
||||
|
||||
# 阶段①:激活账号并建项目与需求台账(API;需 serve)。
|
||||
# 阶段①:超管会话 + 管理 API 建号,再建项目与需求台账(API;需 serve)。
|
||||
start_serve
|
||||
JAR="$OUT/cookies.txt"
|
||||
log "seed: identity ensure + base first account (login-key 契约)"
|
||||
log "seed: identity ensure + base first account (SUPER_ADMIN session)"
|
||||
ID_OK=0
|
||||
for i in $(seq 1 15); do
|
||||
if "$OUT/agent-system" identity ensure --data "$DATA" --instance-id "e2e-audit" >/dev/null 2>&1; then ID_OK=1; break; fi
|
||||
sleep 1 # 服务端受控迁移(含 identity 表)可能晚于 HTTP 就绪
|
||||
done
|
||||
[ "$ID_OK" = 1 ] || { tail -5 "$OUT/serve.log"; die "identity ensure failed"; }
|
||||
"$OUT/agent-system" user bootstrap-admin --data "$DATA" --owner "$OWNER" \
|
||||
--name "E2E 审计员" --out-file "$OUT/$OWNER.bootstrap.key" >/dev/null \
|
||||
|| die "base bootstrap-admin failed"
|
||||
K=$(cat "$OUT/$OWNER.bootstrap.key")
|
||||
curl -sf -c "$JAR" -X POST "$API_BASE/api/auth/login-key/redeem" \
|
||||
-H 'Content-Type: application/json' -d "{\"key\":\"$K\"}" >/dev/null || die "login-key redeem failed"
|
||||
# 激活会话仅能设密:设为 PASSWORD2(后续登录与规格消费一致)。
|
||||
curl -sf -b "$JAR" -c "$JAR" -X POST "$API_BASE/api/auth/password" \
|
||||
-H 'Content-Type: application/json' -d "{\"next\":\"$PASSWORD2\"}" >/dev/null || die "password setup failed"
|
||||
PASSWORD=$PASSWORD2
|
||||
# Legacy bootstrap-admin is disabled; super admin is established at serve startup
|
||||
# from SUPER_ADMIN_OWNER/SUPER_ADMIN_PASSWORD. Login via the normal session endpoint.
|
||||
login
|
||||
# Fixture owner(默认 e2e-auditor):RDM -bootstrap-admin 已授域管理员;此处再建基座账号
|
||||
# 并任命 isAdmin(admin-user-create 需「系统管理…」)。初始密码=PASSWORD,mustChange
|
||||
# 由 Playwright 首登改密门处理为 PASSWORD2(不覆盖超管会话 jar)。
|
||||
admin_create_user "$OWNER" "$PASSWORD" "$OWNER" true
|
||||
log "seed: create projects"
|
||||
PID_MAIN=$(cmd rdm.project.create "{\"name\":\"$PROJ_MAIN\"}" | python3 -c 'import json,sys; print(json.load(sys.stdin)["projectId"])')
|
||||
read -r PID_MAIN HOST_MAIN < <(cmd rdm.project.create "{\"name\":\"$PROJ_MAIN\"}" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d["projectId"], d["hostProjectId"])')
|
||||
[ -n "${HOST_MAIN:-}" ] || die "rdm.project.create: missing projectId/hostProjectId"
|
||||
PID_ISO=$(cmd rdm.project.create "{\"name\":\"$PROJ_ISO\"}" | python3 -c 'import json,sys; print(json.load(sys.stdin)["projectId"])')
|
||||
log "seed: projects main=$PID_MAIN iso=$PID_ISO"
|
||||
log "seed: projects main=$PID_MAIN (host $HOST_MAIN) iso=$PID_ISO"
|
||||
|
||||
# I1 requires a current business grant even for a project creator or system
|
||||
# administrator. Both projects are ordinary test fixtures in this private data root.
|
||||
log "seed: grant explicit audit.read for the fixture owner"
|
||||
# Projects are created under the SUPER_ADMIN session (immutable creator). The
|
||||
# Playwright fixture owner is a separate account: add it as project owner so
|
||||
# doc visibility comes from membership + member-role defaults.
|
||||
log "seed: add fixture owner as project member (owner role; doc via member defaults)"
|
||||
cmd rdm.project.member.add "{\"projectId\":\"$PID_MAIN\",\"member\":\"$OWNER\",\"role\":\"owner\"}" >/dev/null
|
||||
cmd rdm.project.member.add "{\"projectId\":\"$PID_ISO\",\"member\":\"$OWNER\",\"role\":\"owner\"}" >/dev/null
|
||||
# audit.read is never a member-role default and its platform cap ships closed
|
||||
# (rdm_perm_caps audit.read=0): open the cap, then grant it explicitly per project
|
||||
# (rdm.perm.set is rejected above the cap).
|
||||
log "seed: audit.read cap + explicit grant to fixture owner on both projects"
|
||||
cmd rdm.perm.cap '{"action":"audit.read","allow":true}' >/dev/null
|
||||
cmd rdm.perm.set "{\"projectId\":\"$PID_MAIN\",\"member\":\"$OWNER\",\"action\":\"audit.read\",\"allow\":true}" >/dev/null
|
||||
cmd rdm.perm.set "{\"projectId\":\"$PID_ISO\",\"member\":\"$OWNER\",\"action\":\"audit.read\",\"allow\":true}" >/dev/null
|
||||
|
||||
log "seed: grant explicit doc.read for the cockpit fixture owner"
|
||||
cmd rdm.perm.set "{\"projectId\":\"$PID_MAIN\",\"member\":\"$OWNER\",\"action\":\"doc.read\",\"allow\":true}" >/dev/null
|
||||
cmd rdm.perm.set "{\"projectId\":\"$PID_ISO\",\"member\":\"$OWNER\",\"action\":\"doc.read\",\"allow\":true}" >/dev/null
|
||||
for p in "$PID_MAIN" "$PID_ISO"; do
|
||||
cmd rdm.perm.set "{\"projectId\":\"$p\",\"member\":\"$OWNER\",\"action\":\"audit.read\",\"allow\":true}" >/dev/null
|
||||
done
|
||||
|
||||
log "seed: conversation source in $HOST_MAIN (formal project commands)"
|
||||
seed_source "$HOST_MAIN"
|
||||
log "seed: import requirement ledger into $PID_MAIN"
|
||||
cmd rdm.reqs.import "{\"projectId\":\"$PID_MAIN\",\"items\":$(
|
||||
fcmd rdm.reqs.import "{\"projectId\":\"$PID_MAIN\",\"items\":$(
|
||||
python3 - <<'PY'
|
||||
import json
|
||||
rows = [
|
||||
@@ -228,33 +294,35 @@ SEED_MD='# 用户需求与系统需求
|
||||
审计工作区按项目隔离读取;管理员可跨项目目录进入。事件按操作归组,
|
||||
历史模式按 seq 还原,缺失事实明确标注不可恢复。'
|
||||
log "seed: ingest corpus into $PID_MAIN"
|
||||
cmd rdm.ingest "{\"projectId\":\"$PID_MAIN\",\"source\":\"01-用户需求与系统需求.md\",\"stage\":\"BD\",\"text\":$(python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))' <<<"$SEED_MD")}" >/dev/null
|
||||
fcmd rdm.ingest "{\"projectId\":\"$PID_MAIN\",\"source\":\"01-用户需求与系统需求.md\",\"stage\":\"BD\",\"text\":$(python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))' <<<"$SEED_MD")}" >/dev/null
|
||||
log "seed done"
|
||||
|
||||
# ── 驾驶舱 I4 种子:章节探针提案 + 非成员账号(正文经结构 YAML 装载) ──
|
||||
cmd rdm.perm.set "{\"projectId\":\"$PID_MAIN\",\"member\":\"$OWNER\",\"action\":\"doc.write\",\"allow\":true}" >/dev/null
|
||||
# Fixture owner already holds doc.write via owner membership defaults; seed
|
||||
# draft.propose runs as SUPER_ADMIN (project creator) and needs no perm.set.
|
||||
log "seed: cockpit pending proposal probe (non-danger; scenario 4)"
|
||||
COCKPIT_OV=$(cmd rdm.cockpit.overview "{\"projectId\":\"$PID_MAIN\"}")
|
||||
DOC_ID=$(printf '%s' "$COCKPIT_OV" | python3 -c 'import json,sys; d=json.load(sys.stdin); print([i["ref"]["id"] for i in d["documents"] if i["title"]=="验证主体报告"][0])')
|
||||
SEC_JSON=$(cmd rdm.cockpit.tree "{\"projectId\":\"$PID_MAIN\",\"parent\":\"$DOC_ID\"}")
|
||||
SEC_DESIGN=$(printf '%s' "$SEC_JSON" | python3 -c 'import json,sys; d=json.load(sys.stdin); print([i["ref"]["id"] for i in d["items"] if i["title"]=="设计说明"][0])')
|
||||
# 场景 4 驱动用:留一个未采纳提案(浏览器内经 API 采纳后观察投影一致)。
|
||||
cmd rdm.draft.propose "{\"projectId\":\"$PID_MAIN\",\"sectionId\":\"$SEC_DESIGN\",\"content\":\"一致性探针内容。\"}" >/dev/null
|
||||
fcmd rdm.draft.propose "{\"projectId\":\"$PID_MAIN\",\"sectionId\":\"$SEC_DESIGN\",\"content\":\"一致性探针内容。\"}" >/dev/null
|
||||
# 场景 2 驱动:验证主体报告设文档级三权(职责判据与正文版本作者无关;
|
||||
# 结构装载作者为 structure,owner 经文档职责获得正文可读)。
|
||||
log "seed: duty accounts + doc-level duties (scenario 2)"
|
||||
DOC_MAIN=$(printf '%s' "$COCKPIT_OV" | python3 -c 'import json,sys; d=json.load(sys.stdin); print([i["ref"]["id"] for i in d["documents"] if i["title"]=="验证主体报告"][0])')
|
||||
"$OUT/agent-system" user create --data "$DATA" --owner e2e-rev --out-file "$OUT/e2e-rev.bootstrap.key" >/dev/null || die "rev create failed"
|
||||
"$OUT/agent-system" user create --data "$DATA" --owner e2e-app --out-file "$OUT/e2e-app.bootstrap.key" >/dev/null || die "app create failed"
|
||||
admin_create_user e2e-rev 'E2eRev#2026' e2e-rev
|
||||
admin_create_user e2e-app 'E2eApp#2026' e2e-app
|
||||
cmd rdm.project.member.add "{\"projectId\":\"$PID_MAIN\",\"member\":\"e2e-rev\",\"role\":\"member\"}" >/dev/null
|
||||
cmd rdm.project.member.add "{\"projectId\":\"$PID_MAIN\",\"member\":\"e2e-app\",\"role\":\"member\"}" >/dev/null
|
||||
cmd rdm.review.assign.doc "{\"projectId\":\"$PID_MAIN\",\"docId\":\"$DOC_MAIN\",\"author\":\"$OWNER\",\"reviewers\":[\"e2e-rev\"],\"approver\":\"e2e-app\"}" >/dev/null
|
||||
fcmd rdm.review.assign.doc "{\"projectId\":\"$PID_MAIN\",\"docId\":\"$DOC_MAIN\",\"author\":\"$OWNER\",\"reviewers\":[\"e2e-rev\"],\"approver\":\"e2e-app\"}" >/dev/null
|
||||
log "seed: second account (non-member negative case)"
|
||||
"$OUT/agent-system" user create --data "$DATA" --owner e2e-reader --out-file "$OUT/e2e-reader.bootstrap.key" >/dev/null || die "reader create failed"
|
||||
K2=$(cat "$OUT/e2e-reader.bootstrap.key")
|
||||
JAR2="$OUT/reader.jar"
|
||||
curl -sf -c "$JAR2" -X POST "$API_BASE/api/auth/login-key/redeem" -H 'Content-Type: application/json' -d "{\"key\":\"$K2\",\"owner\":\"e2e-reader\"}" >/dev/null || die "reader redeem failed"
|
||||
curl -sf -b "$JAR2" -c "$JAR2" -X POST "$API_BASE/api/auth/password" -H 'Content-Type: application/json' -d "{\"next\":\"E2eReader#2026\"}" >/dev/null || die "reader password setup failed"
|
||||
# cockpit 场景 6 直接以 E2E_READER_PASSWORD 登录(无改密门);种子代完 must-change,
|
||||
# 使最终密码与 Playwright 缺省 E2eReader#2026 一致。
|
||||
READER=${E2E_READER:-e2e-reader}
|
||||
READER_PASSWORD=${E2E_READER_PASSWORD:-E2eReader#2026}
|
||||
admin_create_user "$READER" "$READER_PASSWORD" "$READER"
|
||||
complete_must_change "$READER" "$READER_PASSWORD" "$READER_PASSWORD"
|
||||
|
||||
# ── 3. 验收 ─────────────────────────────────────────────
|
||||
if [ "$SEED_ONLY" = 1 ]; then
|
||||
@@ -284,11 +352,12 @@ log "playwright (install chromium if missing)"
|
||||
log "run specs"
|
||||
cd "$DEV_ROOT/modules/frontend"
|
||||
export PLAYWRIGHT_BASE_URL="http://127.0.0.1:$UI_PORT" E2E_OWNER="$OWNER" \
|
||||
E2E_PASSWORD="${E2E_PASSWORD:-E2eAudit#2026}" E2E_PASSWORD2="$PASSWORD2" \
|
||||
E2E_PASSWORD="$PASSWORD" E2E_PASSWORD2="$PASSWORD2" \
|
||||
E2E_READER="$READER" E2E_READER_PASSWORD="$READER_PASSWORD" \
|
||||
E2E_PROJECT_MAIN="$PROJ_MAIN" E2E_PROJECT_ISOLATED="$PROJ_ISO"
|
||||
set +e
|
||||
# 本脚本的种子只覆盖审计工作区。u7 现场验收用例依赖另一套入口,不在这里跑。
|
||||
# admin-create 场景复用本种子的基座管理员账号(bootstrap-admin)。
|
||||
# admin-create 场景复用本种子的基座超管会话(SUPER_ADMIN_*)。
|
||||
npx playwright test e2e/rdm-audit.playwright.ts e2e/rdm-cockpit.playwright.ts e2e/admin-user-create.playwright.ts --reporter=list >"$OUT/playwright.log" 2>&1
|
||||
PW_EXIT=$?
|
||||
set -e
|
||||
|
||||
Reference in New Issue
Block a user