fix(home): send starter cards instead of filling the composer
Independent Staging Quality Gate / validate (push) Successful in 11m21s
Independent Staging Quality Gate / publish (push) Successful in 17m56s

Clicking today's reading or a topic card should open a consultation and wait for the model, not leave the question in the input box.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-21 22:02:40 +08:00
parent cf168a54c0
commit 649ba32034
7 changed files with 70 additions and 18 deletions
@@ -81,7 +81,7 @@ test("every external draft writer keeps working through the page-owned setters",
assert.match(pageSource, /onChange=\{\(event\) => \{\n\s*setDraft\(event\.target\.value\);\n\s*setDraftTheme\(null\);\n\s*setDraftEntrypoint\(null\);\n\s*setComposerNotice\(""\);\n\s*\}\}/);
// When: each existing write path is inspected.
const chooseSuggested = sourceBetween(pageSource, "function chooseSuggestedQuestion(", "function draftDailyStarlanguageQuestion");
const chooseSuggested = sourceBetween(pageSource, "function chooseSuggestedQuestion(", "async function startSuggestedConsultation");
const startNewChat = sourceBetween(pageSource, "async function startNewChat()", "function selectSession(");
const selectSession = sourceBetween(pageSource, "function selectSession(sessionId: string)", "async function selectSessionModel");
const saveOnboardingName = sourceBetween(pageSource, "async function saveOnboardingName()", "async function saveOnboardingBirth");
@@ -93,8 +93,11 @@ test("every external draft writer keeps working through the page-owned setters",
"setRequestError({",
);
// Then: suggestions fill, session switches clear, stop restores and send clears.
// Then: synastry still fills the composer; session switches clear, stop restores and send clears.
assert.match(chooseSuggested, /setDraft\(question\);\n\s*setDraftTheme\(theme \?\? null\);\n\s*setDraftEntrypoint\(entrypoint\);/);
const startSuggested = sourceBetween(pageSource, "async function startSuggestedConsultation(", "function startDailyStarlanguageConsultation");
assert.match(startSuggested, /await send\(trimmed, theme, entrypoint, null, targetSession\.id/);
assert.doesNotMatch(startSuggested, /setDraft\(/);
assert.match(startNewChat, /setDraft\(""\)/);
assert.match(selectSession, /setDraft\(""\)/);
assert.match(saveOnboardingName, /composerDraftSnapshot\(\)\.replace\(/);
@@ -129,7 +129,7 @@ test("ordinary product drafts keep the public question and clear hidden routing
assert.match(source, /dailyStarlanguageQuestion/);
assert.match(source, /从今日问起/);
assert.match(source, /深入看今日/);
assert.match(source, /chooseSuggestedQuestion\(\s*dailyStarlanguageQuestion,\s*"timing",\s*"daily_starlanguage"/);
assert.match(source, /startSuggestedConsultation\(\s*dailyStarlanguageQuestion,\s*"timing",\s*"daily_starlanguage"/);
assert.match(source, /consultEntrypoint === "birth_time_rectification"/);
assert.match(source, /isRectificationHandoffQuestion\(question\)/);
assert.match(source, /openRectificationFromHomepage\(pendingQuestion\)/);
+19 -2
View File
@@ -46,7 +46,7 @@ test("default starter questions derive every canonical domain with evidence and
assert.match(pageSource, /defaultGuidedJyotishTopics/);
assert.match(pageSource, /starterSuggestions\.map/);
assert.match(pageSource, /starterThemes\.find\(\(candidate\) => candidate\.id === item\.theme\)/);
assert.match(pageSource, /chooseSuggestedQuestion\(item\.text, item\.theme\)/);
assert.match(pageSource, /void startSuggestedConsultation\(item\.text, item\.theme\)/);
assert.equal(consultationDomainIds.length, 10);
assert.deepEqual(consultationDomainRegistry.map((domain) => domain.id), [...consultationDomainIds]);
assert.match(guidedTopicsSource, /consultationDomainRegistry\.map/);
@@ -106,10 +106,27 @@ test("profiles without a usable birth minute receive user-centered starter promp
assert.match(themeSectionHeading, /natalMinuteAvailable/);
assert.match(themeSectionHeading, /出生时间不足以支持的部分,我会明确说明,不会补造具体分钟/);
assert.match(pageSource, /GENERAL_NO_MINUTE_DAILY_FORTUNE_QUESTION/);
assert.match(pageSource, /chooseSuggestedQuestion\(\s*dailyStarlanguageQuestion,\s*"timing",\s*"daily_starlanguage"/);
assert.match(pageSource, /startSuggestedConsultation\(\s*dailyStarlanguageQuestion,\s*"timing",\s*"daily_starlanguage"/);
assert.doesNotMatch(pageSource, /personalChartAvailable \? "daily_starlanguage" : null/);
});
test("homepage daily and topic cards start a consultation instead of filling the composer", () => {
const starterSend = sourceBetween(
pageSource,
"async function startSuggestedConsultation(",
"function startDailyStarlanguageConsultation",
);
assert.match(pageSource, /onClick=\{startDailyStarlanguageConsultation\}/);
assert.match(pageSource, /onClick=\{\(\) => void startSuggestedConsultation\(item\.text, item\.theme\)\}/);
assert.doesNotMatch(pageSource, /draftDailyStarlanguageQuestion/);
assert.doesNotMatch(pageSource, /onClick=\{\(\) => chooseSuggestedQuestion\(item\.text, item\.theme\)\}/);
assert.match(starterSend, /await startNewChat\(\)/);
assert.match(starterSend, /await send\(trimmed, theme, entrypoint, null, targetSession\.id/);
assert.doesNotMatch(starterSend, /setDraft\(/);
assert.doesNotMatch(starterSend, /composerInput\.current\?\.focus/);
});
test("keeps session history clickable while another session is answering", () => {
// Given: the page-owned selection callback and the app sidebar session action.