Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
149 lines
5.9 KiB
TypeScript
149 lines
5.9 KiB
TypeScript
import assert from "node:assert/strict";
|
||
import { readFileSync } from "node:fs";
|
||
import test from "node:test";
|
||
import React from "react";
|
||
import { renderToStaticMarkup } from "react-dom/server";
|
||
|
||
import { HomeBootstrapError } from "../src/components/home-bootstrap-error.tsx";
|
||
import { HomeOnboardingShell } from "../src/components/home-onboarding-shell.tsx";
|
||
import type { BirthTimeGuidedController } from "../src/hooks/use-birth-time-guided-journey.ts";
|
||
import { emptyProfile, presetOnboardingMessage } from "../src/lib/home-types.ts";
|
||
import { createClientLifecycleHarness } from "./react-client-lifecycle-test-support.ts";
|
||
|
||
Object.assign(globalThis, { React });
|
||
|
||
const page = readFileSync(new URL("../src/app/(app)/page.tsx", import.meta.url), "utf8");
|
||
|
||
test("the fatal screen keeps its copy and retries through retryHomeBootstrap", async () => {
|
||
const accountError = "连接云端服务超时。请检查网络后重试,或返回登录页重新建立会话。";
|
||
const markup = renderToStaticMarkup(
|
||
<HomeBootstrapError accountError={accountError} onRetry={() => undefined} />,
|
||
);
|
||
assert.match(markup, /暂时无法进入 Jyotisha/);
|
||
assert.match(markup, /连接云端服务超时。请检查网络后重试,或返回登录页重新建立会话。/);
|
||
assert.match(markup, /重试/);
|
||
assert.match(markup, /返回登录/);
|
||
assert.match(markup, /app-loading app-loading-error/);
|
||
assert.match(markup, /role="alert"/);
|
||
|
||
const harness = createClientLifecycleHarness();
|
||
let retried = 0;
|
||
try {
|
||
await harness.render(<HomeBootstrapError accountError={accountError} onRetry={() => { retried += 1; }} />);
|
||
const retry = harness.elements().find((node) => node.tagName === "BUTTON" && node.text.includes("重试"));
|
||
assert.ok(retry);
|
||
await harness.event(retry);
|
||
assert.equal(retried, 1);
|
||
} finally {
|
||
await harness.close();
|
||
}
|
||
|
||
// 原值:错误屏按钮内联在 page.tsx,onClick 直接调用 retryHomeBootstrap。
|
||
// 新值:按钮在 HomeBootstrapError,page.tsx 把 onRetry 接到同一个 retryHomeBootstrap(...reloadSessionList)。
|
||
// 原因:错误屏抽成组件后,重试仍局部重跑,不整页刷新。
|
||
assert.match(page, /<HomeBootstrapError[\s\S]*onRetry=\{\(\) => retryHomeBootstrap\([\s\S]*reloadSessionList,[\s\S]*\)\}/);
|
||
assert.doesNotMatch(page, /window\.location\.reload\(\)/);
|
||
});
|
||
|
||
test("onboarding keeps the name prompt, birth card, place card, and retry card", () => {
|
||
const guided = {} as BirthTimeGuidedController;
|
||
const nameMarkup = renderToStaticMarkup(
|
||
<HomeOnboardingShell
|
||
profileComplete={false}
|
||
profileDraft={emptyProfile}
|
||
setProfileDraft={() => undefined}
|
||
onboardingStep="name"
|
||
presetMessageLength={presetOnboardingMessage.length}
|
||
currentOnboardingMessage={presetOnboardingMessage}
|
||
onboardingJustCompleted={false}
|
||
onboardingCardReady={false}
|
||
presetMessageFinished
|
||
birthTimeJourney={null}
|
||
birthTimeAssessmentPhase={null}
|
||
birthTimeError=""
|
||
birthTimeGuided={guided}
|
||
profileSaving={false}
|
||
saveOnboardingBirth={() => undefined}
|
||
saveOnboardingPlace={() => undefined}
|
||
retryBirthTimeAssessment={() => undefined}
|
||
/>,
|
||
);
|
||
assert.match(nameMarkup, /你好,我是 Jyotisha/);
|
||
assert.match(nameMarkup, /请问我该怎么称呼你/);
|
||
assert.doesNotMatch(nameMarkup, /出生日期与时间/);
|
||
|
||
const birthMarkup = renderToStaticMarkup(
|
||
<HomeOnboardingShell
|
||
profileComplete={false}
|
||
profileDraft={{ ...emptyProfile, name: "林遥" }}
|
||
setProfileDraft={() => undefined}
|
||
onboardingStep="birth"
|
||
presetMessageLength={80}
|
||
currentOnboardingMessage="出生时间"
|
||
onboardingJustCompleted={false}
|
||
onboardingCardReady
|
||
presetMessageFinished
|
||
birthTimeJourney={null}
|
||
birthTimeAssessmentPhase={null}
|
||
birthTimeError=""
|
||
birthTimeGuided={guided}
|
||
profileSaving={false}
|
||
saveOnboardingBirth={() => undefined}
|
||
saveOnboardingPlace={() => undefined}
|
||
retryBirthTimeAssessment={() => undefined}
|
||
/>,
|
||
);
|
||
assert.match(birthMarkup, /出生日期与时间/);
|
||
assert.match(birthMarkup, />继续</);
|
||
|
||
const placeMarkup = renderToStaticMarkup(
|
||
<HomeOnboardingShell
|
||
profileComplete={false}
|
||
profileDraft={{ ...emptyProfile, name: "林遥" }}
|
||
setProfileDraft={() => undefined}
|
||
onboardingStep="place"
|
||
presetMessageLength={80}
|
||
currentOnboardingMessage="出生地点"
|
||
onboardingJustCompleted={false}
|
||
onboardingCardReady
|
||
presetMessageFinished
|
||
birthTimeJourney={null}
|
||
birthTimeAssessmentPhase={null}
|
||
birthTimeError=""
|
||
birthTimeGuided={guided}
|
||
profileSaving={false}
|
||
saveOnboardingBirth={() => undefined}
|
||
saveOnboardingPlace={() => undefined}
|
||
retryBirthTimeAssessment={() => undefined}
|
||
/>,
|
||
);
|
||
assert.match(placeMarkup, /出生地点/);
|
||
assert.match(placeMarkup, /搜索全球城市或区县,系统会匹配出生当日的时区。/);
|
||
assert.match(placeMarkup, />确定</);
|
||
|
||
const retryMarkup = renderToStaticMarkup(
|
||
<HomeOnboardingShell
|
||
profileComplete={false}
|
||
profileDraft={{ ...emptyProfile, name: "林遥" }}
|
||
setProfileDraft={() => undefined}
|
||
onboardingStep="rectification"
|
||
presetMessageLength={80}
|
||
currentOnboardingMessage="校正"
|
||
onboardingJustCompleted={false}
|
||
onboardingCardReady
|
||
presetMessageFinished
|
||
birthTimeJourney={null}
|
||
birthTimeAssessmentPhase={null}
|
||
birthTimeError=""
|
||
birthTimeGuided={guided}
|
||
profileSaving={false}
|
||
saveOnboardingBirth={() => undefined}
|
||
saveOnboardingPlace={() => undefined}
|
||
retryBirthTimeAssessment={() => undefined}
|
||
/>,
|
||
);
|
||
assert.match(retryMarkup, /出生时间尚未完成评估/);
|
||
assert.match(retryMarkup, /资料已经保留,但暂时无法恢复校正进度。系统不会应用未经验证的具体时间。/);
|
||
assert.match(retryMarkup, />重新评估</);
|
||
});
|