fix: refine heaven readings and heart breathing

This commit is contained in:
leefer
2026-07-23 20:15:30 +08:00
parent 95789c837c
commit e6db73f9ba
4 changed files with 170 additions and 23 deletions
+41 -1
View File
@@ -313,7 +313,7 @@ test("saved daily fortune opens in the reading dialog without regenerating", asy
context_date: "20260723",
subject: "2026-07-23 观气",
subject_detail: "丙午年 · 乙未月 · 己丑日 · 土气偏显",
answer: "三层气机已经合参,今日宜先定节奏,再看行动。",
answer: Array.from({ length: 36 }, (_, index) => `${index + 1}节:三层气机已经合参,今日宜先定节奏,再看行动。`).join("\n\n"),
created_at: "2026-07-23T09:12:00+08:00",
};
updateHeavenInterpretationControls();
@@ -326,11 +326,51 @@ test("saved daily fortune opens in the reading dialog without regenerating", asy
await page.locator("#interpretFortuneButton").click();
await expect(page.locator("#heavenReadingDialog")).toBeVisible();
await expect(page.locator("#heavenReadingAnswer")).toContainText("今日宜先定节奏");
const readingScroll = await page.locator("#heavenReadingCurrent").evaluate((element) => ({
clientHeight: element.clientHeight,
scrollHeight: element.scrollHeight,
overflowY: getComputedStyle(element).overflowY,
}));
expect(readingScroll.scrollHeight).toBeGreaterThan(readingScroll.clientHeight);
expect(readingScroll.overflowY).toBe("auto");
await page.locator("#heavenReadingCurrent").evaluate((element) => { element.scrollTop = element.scrollHeight; });
expect(await page.locator("#heavenReadingCurrent").evaluate((element) => element.scrollTop)).toBeGreaterThan(0);
expect(interpretRequests).toHaveLength(0);
await page.locator('[data-heaven-reading-tab="history"]').click();
await expect(page.locator("#heavenReadingHistoryList .heaven-reading-history-item")).toHaveCount(1);
});
test("heart breathing uses five silent eight-second cycles with a fixed enso", async ({ page }) => {
await mockApplication(page, session("user", true));
await page.goto("/index.html");
await page.locator('[data-view="heavenView"]').first().click();
await page.locator('[data-heaven-panel="heart"]').click();
await page.evaluate(() => startHeartBreathing());
const timing = await page.evaluate(() => ({
remaining: state.heartBreathingEndsAt - Date.now(),
incenseDuration: getComputedStyle(document.querySelector("#heartIncenseEmber")).animationDuration,
inhaleTransform: getComputedStyle(document.querySelector(".heart-breath-enso")).transform,
}));
expect(timing.remaining).toBeGreaterThan(39_000);
expect(timing.remaining).toBeLessThanOrEqual(40_000);
expect(timing.incenseDuration).toBe("40s");
await expect(page.locator("#breathingPhase")).toHaveText("吸气");
await expect(page.locator("#breathingSeconds, #breathingProgress, .breathing-orbit")).toHaveCount(0);
const exhaleTransform = await page.evaluate(() => {
clearInterval(state.heartTimer);
state.heartTimer = null;
state.heartSeconds = 35;
state.heartBreathingEndsAt = Date.now() + 35_000;
updateBreathingDisplay();
return getComputedStyle(document.querySelector(".heart-breath-enso")).transform;
});
await expect(page.locator("#breathingScene")).toHaveAttribute("data-phase", "exhale");
await expect(page.locator("#breathingPhase")).toHaveText("呼气");
expect(exhaleTransform).toBe(timing.inhaleTransform);
});
test("mobile shell stays within the viewport", async ({ page }) => {
await page.setViewportSize({ width: 375, height: 812 });
await mockApplication(page, session("user", true));