fix: preserve turn anchors when prepending history
This commit is contained in:
@@ -97,11 +97,11 @@ Deno.test("production Console pages backward by real turns while preserving both
|
|||||||
}\nerrors=${JSON.stringify(errors)}\nbody=${await page.locator("body").innerText()}`,
|
}\nerrors=${JSON.stringify(errors)}\nbody=${await page.locator("body").innerText()}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const navigation = page.getByRole("complementary", { name: "Conversation turns" });
|
const navigation = page.getByRole("navigation", { name: "Conversation turns" });
|
||||||
await navigation.getByText("question 7", { exact: true }).waitFor();
|
await navigation.getByRole("button", { name: /^Turn \d+: question 7$/ }).waitFor();
|
||||||
assertEquals(await historyRequestCount(baseUrl), 1);
|
assertEquals(await historyRequestCount(baseUrl), 1);
|
||||||
assertEquals(await transcript.getByText(/^question (7|8|9|10|11|12)$/).count(), 6);
|
assertEquals(await transcript.getByText(/^question (7|8|9|10|11|12)$/).count(), 6);
|
||||||
assertEquals(await navigation.getByText(/^question (7|8|9|10|11|12)$/).count(), 6);
|
assertEquals(await navigation.getByRole("button", { name: /^Turn \d+: question (7|8|9|10|11|12)$/ }).count(), 6);
|
||||||
const currentQuestionTop = await transcript
|
const currentQuestionTop = await transcript
|
||||||
.getByText("question 7", { exact: true })
|
.getByText("question 7", { exact: true })
|
||||||
.evaluate((element) => element.getBoundingClientRect().top);
|
.evaluate((element) => element.getBoundingClientRect().top);
|
||||||
@@ -114,13 +114,15 @@ Deno.test("production Console pages backward by real turns while preserving both
|
|||||||
);
|
);
|
||||||
|
|
||||||
const question12 = navigation.getByRole("button", {
|
const question12 = navigation.getByRole("button", {
|
||||||
name: "Jump to conversation: question 12",
|
name: /^Turn \d+: question 12$/,
|
||||||
});
|
});
|
||||||
assertEquals(await question12.getByText("detail 12.1", { exact: true }).count(), 1);
|
await question12.hover();
|
||||||
assertEquals(await question12.getByText("detail 12.2", { exact: true }).count(), 1);
|
const preview = navigation.getByRole("tooltip");
|
||||||
assertEquals(await question12.getByText("detail 12.3", { exact: true }).count(), 0);
|
await preview.waitFor();
|
||||||
assert(!(await question12.textContent())?.includes("User"));
|
assert((await preview.textContent())?.includes("detail 12.1"));
|
||||||
assert(!(await question12.textContent())?.includes("AI"));
|
assert((await preview.textContent())?.includes("detail 12.2"));
|
||||||
|
assert(!(await preview.textContent())?.includes("detail 12.3"));
|
||||||
|
await page.keyboard.press("Escape");
|
||||||
|
|
||||||
const consoleScroll = transcript.locator("xpath=..");
|
const consoleScroll = transcript.locator("xpath=..");
|
||||||
const topAlignment = await page.evaluate(() => {
|
const topAlignment = await page.evaluate(() => {
|
||||||
@@ -142,7 +144,7 @@ Deno.test("production Console pages backward by real turns while preserving both
|
|||||||
return top;
|
return top;
|
||||||
});
|
});
|
||||||
await transcript.getByText("question 3", { exact: true }).waitFor();
|
await transcript.getByText("question 3", { exact: true }).waitFor();
|
||||||
await navigation.getByText("question 3", { exact: true }).waitFor();
|
await navigation.getByRole("button", { name: /^Turn \d+: question 3$/ }).waitFor();
|
||||||
const restoredTop = await transcript
|
const restoredTop = await transcript
|
||||||
.locator('[data-console-line-id*="user-8"]')
|
.locator('[data-console-line-id*="user-8"]')
|
||||||
.evaluate((element) => element.getBoundingClientRect().top);
|
.evaluate((element) => element.getBoundingClientRect().top);
|
||||||
@@ -172,12 +174,12 @@ Deno.test("production Console pages backward by real turns while preserving both
|
|||||||
element.dispatchEvent(new Event("scroll"));
|
element.dispatchEvent(new Event("scroll"));
|
||||||
});
|
});
|
||||||
await transcript.getByText("question 1", { exact: true }).waitFor();
|
await transcript.getByText("question 1", { exact: true }).waitFor();
|
||||||
await navigation.getByText("question 1", { exact: true }).waitFor();
|
await navigation.getByRole("button", { name: /^Turn \d+: question 1$/ }).waitFor();
|
||||||
assertEquals(await historyRequestCount(baseUrl), 3);
|
assertEquals(await historyRequestCount(baseUrl), 3);
|
||||||
assertEquals(await page.getByText("Start of conversation", { exact: true }).count(), 2);
|
assertEquals(await page.getByText("Start of conversation", { exact: true }).count(), 1);
|
||||||
|
|
||||||
await navigation.getByRole("button", {
|
await navigation.getByRole("button", {
|
||||||
name: "Jump to conversation: question 3",
|
name: /^Turn \d+: question 3$/,
|
||||||
}).click();
|
}).click();
|
||||||
await page.waitForFunction(() => {
|
await page.waitForFunction(() => {
|
||||||
const document = (globalThis as any).document;
|
const document = (globalThis as any).document;
|
||||||
@@ -201,7 +203,7 @@ Deno.test("production Console pages backward by real turns while preserving both
|
|||||||
|
|
||||||
const centering = await question12.evaluate((button) => {
|
const centering = await question12.evaluate((button) => {
|
||||||
const turn = button.getBoundingClientRect();
|
const turn = button.getBoundingClientRect();
|
||||||
const bar = button.querySelector(".bar")!.getBoundingClientRect();
|
const bar = button.querySelector(".turn-bar")!.getBoundingClientRect();
|
||||||
return Math.abs((turn.top + turn.bottom) / 2 - (bar.top + bar.bottom) / 2);
|
return Math.abs((turn.top + turn.bottom) / 2 - (bar.top + bar.bottom) / 2);
|
||||||
});
|
});
|
||||||
assert(centering <= 1, `turn marker is not vertically centered (${centering}px)`);
|
assert(centering <= 1, `turn marker is not vertically centered (${centering}px)`);
|
||||||
|
|||||||
@@ -113,7 +113,8 @@
|
|||||||
|
|
||||||
.turn-bars::-webkit-scrollbar { display: none; }
|
.turn-bars::-webkit-scrollbar { display: none; }
|
||||||
|
|
||||||
/* Center short lists without making overflowing turns unreachable. */
|
/* Bottom-align short lists so prepending older turns does not move existing bars.
|
||||||
|
Once overflowing, scroll-anchor restoration keeps those bars in place. */
|
||||||
.history-boundary { margin-top: auto; }
|
.history-boundary { margin-top: auto; }
|
||||||
.history-boundary button, .history-boundary span {
|
.history-boundary button, .history-boundary span {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -127,7 +128,6 @@
|
|||||||
font: inherit;
|
font: inherit;
|
||||||
}
|
}
|
||||||
.history-boundary button { cursor: pointer; color: var(--tui-cyan); }
|
.history-boundary button { cursor: pointer; color: var(--tui-cyan); }
|
||||||
.turn-button:last-child { margin-bottom: auto; }
|
|
||||||
|
|
||||||
.turn-button {
|
.turn-button {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
Reference in New Issue
Block a user