fix(stream-test): refuse final box when element stays off-screen

bringIntoView returned the last boundingBox() unconditionally after the
scroll loop exhausted, so an element still outside the viewport would be
clicked anyway. Validate the final box against the actual viewport bounds
on both axes (innerWidth/innerHeight) and return null otherwise, so
humanClick fails instead of clicking an off-screen coordinate.
This commit is contained in:
javis-bot
2026-06-10 14:18:43 +09:00
parent bbc2fa3f7a
commit 8709f40fd6

View File

@@ -61,7 +61,7 @@ export async function humanClickXY(sx, sy) {
// Bring an element into view using a REAL wheel scroll (not a DOM
// scrollIntoView). Returns its viewport box, or null if it can't be revealed.
async function bringIntoView(page, locator) {
const ih = await page.evaluate(() => window.innerHeight);
const { iw, ih } = await page.evaluate(() => ({ iw: window.innerWidth, ih: window.innerHeight }));
for (let i = 0; i < 14; i++) {
const box = await locator.boundingBox().catch(() => null);
if (box && box.y >= 70 && box.y + box.height <= ih - 70) return box;
@@ -69,7 +69,13 @@ async function bringIntoView(page, locator) {
await xdo(['click', button]); await xdo(['click', button]); await xdo(['click', button]);
await sleep(rand(120, 240));
}
return await locator.boundingBox().catch(() => null);
// Loop exhausted: only accept the final box if it actually lies inside the
// viewport on BOTH axes. Otherwise refuse, so the caller fails instead of
// clicking a coordinate that is still off-screen.
const box = await locator.boundingBox().catch(() => null);
if (!box) return null;
const onScreen = box.x >= 0 && box.y >= 0 && box.x + box.width <= iw && box.y + box.height <= ih;
return onScreen ? box : null;
}
// Locate a Playwright element, real-wheel it into view, move the real cursor