test(app): align scroll hit-test fixture deterministically

This commit is contained in:
Mohamed Boudra
2026-07-12 19:35:11 +00:00
parent 7eee75dd93
commit 74599dfc06
+56 -25
View File
@@ -148,47 +148,78 @@ export async function clickToolCallBesideScrollToBottomButton(page: Page): Promi
bounds: await toolCalls.nth(index).boundingBox(),
})),
);
const candidate = toolCallBounds.find(({ bounds }) => {
if (!bounds) {
return false;
}
const centerY = bounds.y + bounds.height / 2;
return (
bounds.width > 0 &&
centerY >= visibleButtonBounds.y &&
centerY <= visibleButtonBounds.y + visibleButtonBounds.height
);
});
const buttonCenterY = visibleButtonBounds.y + visibleButtonBounds.height / 2;
const candidate = toolCallBounds
.filter(
(entry): entry is { index: number; bounds: NonNullable<typeof entry.bounds> } =>
entry.bounds !== null && entry.bounds.width > 0,
)
.sort(
(left, right) =>
Math.abs(left.bounds.y + left.bounds.height / 2 - buttonCenterY) -
Math.abs(right.bounds.y + right.bounds.height / 2 - buttonCenterY),
)[0];
expect(
candidate,
`No tool-call badge visible within the scroll-button band: ${JSON.stringify({
`Expected at least one rendered tool-call badge: ${JSON.stringify({
buttonBounds,
scrollMetrics: await readScrollMetrics(page),
toolCallBounds,
})}`,
).toBeDefined();
const visibleToolCall = candidate!;
const visibleToolCallBounds = visibleToolCall.bounds!;
const initialToolCallCenterY = visibleToolCall.bounds.y + visibleToolCall.bounds.height / 2;
await getVisibleChatScroll(page).evaluate((scroll, deltaY) => {
(scroll as HTMLElement).scrollTop += deltaY;
}, initialToolCallCenterY - buttonCenterY);
const alignedToolCall = toolCalls.nth(visibleToolCall.index);
await expect
.poll(async () => {
const [currentButtonBounds, currentToolCallBounds] = await Promise.all([
scrollToBottomButton.boundingBox(),
alignedToolCall.boundingBox(),
]);
if (!currentButtonBounds || !currentToolCallBounds) {
return false;
}
const toolCallCenterY = currentToolCallBounds.y + currentToolCallBounds.height / 2;
return (
toolCallCenterY >= currentButtonBounds.y &&
toolCallCenterY <= currentButtonBounds.y + currentButtonBounds.height
);
})
.toBe(true);
const [alignedButtonBounds, visibleToolCallBounds] = await Promise.all([
scrollToBottomButton.boundingBox(),
alignedToolCall.boundingBox(),
]);
expect(alignedButtonBounds, "Expected scroll-to-bottom button to remain visible").not.toBeNull();
expect(
visibleToolCallBounds,
"Expected aligned tool-call badge to remain visible",
).not.toBeNull();
const finalButtonBounds = alignedButtonBounds!;
const finalToolCallBounds = visibleToolCallBounds!;
const clickPoint = {
x: visibleToolCallBounds.x + 24,
y: visibleToolCallBounds.y + visibleToolCallBounds.height / 2,
x: finalToolCallBounds.x + 24,
y: finalToolCallBounds.y + finalToolCallBounds.height / 2,
};
const toolCallReceivesPointer = await toolCalls
.nth(visibleToolCall.index)
.evaluate((toolCall, point) => {
const hit = document.elementFromPoint(point.x, point.y);
return hit !== null && toolCall.contains(hit);
}, clickPoint);
const toolCallReceivesPointer = await alignedToolCall.evaluate((toolCall, point) => {
const hit = document.elementFromPoint(point.x, point.y);
return hit !== null && toolCall.contains(hit);
}, clickPoint);
const hitArea = {
clickPoint,
outsideButton:
clickPoint.x < visibleButtonBounds.x ||
clickPoint.x > visibleButtonBounds.x + visibleButtonBounds.width,
clickPoint.x < finalButtonBounds.x ||
clickPoint.x > finalButtonBounds.x + finalButtonBounds.width,
toolCallReceivesPointer,
withinButtonBand:
clickPoint.y >= visibleButtonBounds.y &&
clickPoint.y <= visibleButtonBounds.y + visibleButtonBounds.height,
clickPoint.y >= finalButtonBounds.y &&
clickPoint.y <= finalButtonBounds.y + finalButtonBounds.height,
};
await page.mouse.click(hitArea.clickPoint.x, hitArea.clickPoint.y);
return {