#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" # shellcheck disable=SC1091 source "$ROOT_DIR/scripts/acceptance/route_acceptance_lib.sh" PORTAL_ACCEPTANCE_ROOT="${PORTAL_ACCEPTANCE_ROOT:-$ROOT_DIR/artifacts/frontend-acceptance-matrix}" TS="${TS:-$(timestamp_token)}" ARTIFACT_DIR="${ARTIFACT_DIR:-$PORTAL_ACCEPTANCE_ROOT/${TS}_portal_public_browser}" PUBLIC_PORTAL_PAGE_URL="${PUBLIC_PORTAL_PAGE_URL:-https://sub.tksea.top/portal/}" PUBLIC_PORTAL_CATALOG_BASE="${PUBLIC_PORTAL_CATALOG_BASE:-https://sub.tksea.top/portal-admin-api/api/portal}" PUBLIC_PORTAL_PROXY_BASE="${PUBLIC_PORTAL_PROXY_BASE:-https://sub.tksea.top/portal-proxy/api/v1}" PORTAL_ACCESS_TOKEN="${PORTAL_ACCESS_TOKEN:-}" CHROMIUM_BIN="${CHROMIUM_BIN:-}" VIRTUAL_TIME_BUDGET="${VIRTUAL_TIME_BUDGET:-5000}" USER_DATA_DIR="$ARTIFACT_DIR/chromium-profile" fail() { echo "FAIL: $*" >&2 exit 1 } assert_contains_file() { local file="$1" local needle="$2" if ! grep -Fq "$needle" "$file"; then fail "expected [$needle] in $file" fi } find_chromium() { if [[ -n "$CHROMIUM_BIN" ]]; then printf '%s\n' "$CHROMIUM_BIN" return 0 fi local candidate for candidate in chromium chromium-browser google-chrome google-chrome-stable; do if command -v "$candidate" >/dev/null 2>&1; then command -v "$candidate" return 0 fi done return 1 } dump_dom() { local label="$1" local url="$2" local output="$ARTIFACT_DIR/${label}.dom.html" "$CHROMIUM_BIN" \ --headless \ --disable-gpu \ --no-sandbox \ --no-proxy-server \ --user-data-dir="$USER_DATA_DIR/$label" \ --virtual-time-budget="$VIRTUAL_TIME_BUDGET" \ --dump-dom \ "$url" >"$output" 2>"$ARTIFACT_DIR/${label}.stderr.txt" printf '%s\n' "$output" } CHROMIUM_BIN="$(find_chromium)" || fail "missing chromium-compatible browser; set CHROMIUM_BIN explicitly" [[ -x "$CHROMIUM_BIN" ]] || fail "chromium binary is not executable: $CHROMIUM_BIN" ensure_artifact_dir mkdir -p "$USER_DATA_DIR" portal_dom="$(dump_dom "00-portal" "$PUBLIC_PORTAL_PAGE_URL")" assert_contains_file "$portal_dom" "Sub2API 多模型接入中心" assert_contains_file "$portal_dom" "逻辑分组目录" assert_contains_file "$portal_dom" "申请 Key 依赖状态" assert_contains_file "$portal_dom" "可直接申请" assert_contains_file "$portal_dom" "可申请,调用前需确认状态" assert_contains_file "$portal_dom" "待补开通" assert_contains_file "$portal_dom" "待人工整理" assert_contains_file "$portal_dom" "仅目录可见" PORTAL_PAGE_URL="$PUBLIC_PORTAL_PAGE_URL" \ PORTAL_CATALOG_BASE="$PUBLIC_PORTAL_CATALOG_BASE" \ PORTAL_PROXY_BASE="$PUBLIC_PORTAL_PROXY_BASE" \ PORTAL_ACCESS_TOKEN="$PORTAL_ACCESS_TOKEN" \ ARTIFACT_DIR="$ARTIFACT_DIR/catalog_api" \ bash "$ROOT_DIR/scripts/acceptance/verify_portal_catalog_ui.sh" >"$ARTIFACT_DIR/portal_catalog.stdout.txt" python3 - "$ARTIFACT_DIR" "$PUBLIC_PORTAL_PAGE_URL" "$PORTAL_ACCESS_TOKEN" >"$ARTIFACT_DIR/99-summary.json" <<'PY' import json import sys from pathlib import Path art_dir = Path(sys.argv[1]) page_url = sys.argv[2] access_token = sys.argv[3] page = (art_dir / "00-portal.dom.html").read_text(encoding="utf-8") catalog_summary = json.loads((art_dir / "catalog_api" / "99-summary.json").read_text(encoding="utf-8")) summary = { "page_url": page_url, "page_title_seen": "Sub2API 多模型接入中心" in page, "logical_group_catalog_seen": "逻辑分组目录" in page, "dependency_panel_seen": "申请 Key 依赖状态" in page, "dependency_state_copy_seen": { "ready": "可直接申请" in page, "granted": "可申请,调用前需确认状态" in page, "pending": "待补开通" in page, "ambiguous": "待人工整理" in page, "catalog_only": "仅目录可见" in page, }, "user_projection_checked": bool(access_token), "catalog_api_summary": catalog_summary, "result": "pass", } print(json.dumps(summary, ensure_ascii=False, indent=2)) PY cat "$ARTIFACT_DIR/99-summary.json"