Skip to content

Commit 0d2b398

Browse files
authored
clean up page methods (#1407)
# why Currently we use multiple overloads for click, scroll, and draganddrop # what changed simplified code to always return a value, that is either an xpath, or empty string # test plan updated tests, and ran them <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Simplified page interaction methods by removing overloads and making returns predictable. click(), hover(), and scroll() now always return a string, and dragAndDrop() returns [fromXpath, toXpath], using empty strings when no XPath is available. - **Refactors** - Removed TypeScript overloads for Page.click, Page.hover, Page.scroll, and Page.dragAndDrop. - click/hover/scroll now return an XPath string or "". - dragAndDrop returns [fromXpath, toXpath] or ["", ""]. - Updated tests to assert empty strings instead of undefined. - **Migration** - Replace any undefined checks with "" (and ["", ""] for dragAndDrop). <sup>Written for commit 0d162af. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. -->
1 parent 6a5496f commit 0d2b398

File tree

5 files changed

+25
-111
lines changed

5 files changed

+25
-111
lines changed

.changeset/shy-bears-dress.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@browserbasehq/stagehand": patch
3+
---
4+
5+
Clean up page methods

packages/core/lib/v3/tests/page-drag-and-drop.spec.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ test.describe("Page.dragAndDrop() - dragging elements", () => {
312312
expect(toXpath.length).toBeGreaterThan(0);
313313
});
314314

315-
test("drag and drop without returnXpath returns void", async () => {
315+
test("drag and drop without returnXpath returns empty strings", async () => {
316316
const page = v3.context.pages()[0];
317317

318318
await page.goto(
@@ -358,9 +358,11 @@ test.describe("Page.dragAndDrop() - dragging elements", () => {
358358
const toX = item2Location.x + item2Location.width / 2;
359359
const toY = item2Location.y + item2Location.height / 2;
360360

361-
const result = await page.dragAndDrop(fromX, fromY, toX, toY);
361+
const [fromXpath, toXpath] = await page.dragAndDrop(fromX, fromY, toX, toY);
362362

363-
expect(result).toBeUndefined();
363+
// Should return empty strings when returnXpath is not set
364+
expect(fromXpath).toBe("");
365+
expect(toXpath).toBe("");
364366
});
365367

366368
test("drag and drop with different mouse buttons", async () => {

packages/core/lib/v3/tests/page-hover.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ test.describe("Page.hover() - mouse hover at coordinates", () => {
107107
expect(xpath.toLowerCase()).toMatch(/div|target/);
108108
});
109109

110-
test("hover without returnXpath returns void", async () => {
110+
test("hover without returnXpath returns empty string", async () => {
111111
const page = v3.context.pages()[0];
112112

113113
await page.goto(
@@ -122,8 +122,8 @@ test.describe("Page.hover() - mouse hover at coordinates", () => {
122122
// Hover without returnXpath
123123
const result = await page.hover(50, 50);
124124

125-
// Should return undefined (void)
126-
expect(result).toBeUndefined();
125+
// Should return empty string
126+
expect(result).toBe("");
127127
});
128128

129129
test("hover triggers CSS :hover styles", async () => {

packages/core/lib/v3/tests/page-scroll.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ test.describe("Page.scroll() - mouse wheel scrolling", () => {
216216
expect(xpath.toLowerCase()).toMatch(/div|target/);
217217
});
218218

219-
test("scroll without returnXpath returns void", async () => {
219+
test("scroll without returnXpath returns empty string", async () => {
220220
const page = v3.context.pages()[0];
221221

222222
await page.goto(
@@ -231,8 +231,8 @@ test.describe("Page.scroll() - mouse wheel scrolling", () => {
231231
// Scroll without returnXpath
232232
const result = await page.scroll(640, 400, 0, 200);
233233

234-
// Should return undefined (void)
235-
expect(result).toBeUndefined();
234+
// Should return empty string
235+
expect(result).toBe("");
236236
});
237237

238238
test("multiple sequential scrolls accumulate", async () => {

packages/core/lib/v3/understudy/page.ts

Lines changed: 9 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,33 +1275,6 @@ export class Page {
12751275
* on the top-level page target's session. Coordinates are relative to the
12761276
* viewport origin (top-left). Does not scroll.
12771277
*/
1278-
async click(
1279-
x: number,
1280-
y: number,
1281-
options: {
1282-
button?: "left" | "right" | "middle";
1283-
clickCount?: number;
1284-
returnXpath: true;
1285-
},
1286-
): Promise<string>;
1287-
async click(
1288-
x: number,
1289-
y: number,
1290-
options?: {
1291-
button?: "left" | "right" | "middle";
1292-
clickCount?: number;
1293-
returnXpath?: false;
1294-
},
1295-
): Promise<void>;
1296-
async click(
1297-
x: number,
1298-
y: number,
1299-
options: {
1300-
button?: "left" | "right" | "middle";
1301-
clickCount?: number;
1302-
returnXpath: boolean;
1303-
},
1304-
): Promise<void | string>;
13051278
@logAction("Page.click")
13061279
async click(
13071280
x: number,
@@ -1311,7 +1284,7 @@ export class Page {
13111284
clickCount?: number;
13121285
returnXpath?: boolean;
13131286
},
1314-
): Promise<void | string> {
1287+
): Promise<string> {
13151288
const button = options?.button ?? "left";
13161289
const clickCount = options?.clickCount ?? 1;
13171290

@@ -1377,30 +1350,21 @@ export class Page {
13771350
clickCount: i,
13781351
} as Protocol.Input.DispatchMouseEventRequest);
13791352
}
1380-
if (options?.returnXpath) return xpathResult ?? "";
1353+
1354+
return xpathResult ?? "";
13811355
}
13821356

13831357
/**
13841358
* Hover at absolute page coordinates (CSS pixels).
13851359
* Dispatches mouseMoved via CDP Input domain on the top-level page target's
13861360
* session.
13871361
*/
1388-
async hover(
1389-
x: number,
1390-
y: number,
1391-
options: { returnXpath: true },
1392-
): Promise<string>;
1393-
async hover(
1394-
x: number,
1395-
y: number,
1396-
options?: { returnXpath?: false },
1397-
): Promise<void>;
13981362
@logAction("Page.hover")
13991363
async hover(
14001364
x: number,
14011365
y: number,
14021366
options?: { returnXpath?: boolean },
1403-
): Promise<void | string> {
1367+
): Promise<string> {
14041368
let xpathResult: string | undefined;
14051369
if (options?.returnXpath) {
14061370
try {
@@ -1443,38 +1407,17 @@ export class Page {
14431407
button: "none",
14441408
} as Protocol.Input.DispatchMouseEventRequest);
14451409

1446-
if (options?.returnXpath) return xpathResult ?? "";
1410+
return xpathResult ?? "";
14471411
}
14481412

1449-
async scroll(
1450-
x: number,
1451-
y: number,
1452-
deltaX: number,
1453-
deltaY: number,
1454-
options: { returnXpath: true },
1455-
): Promise<string>;
1456-
async scroll(
1457-
x: number,
1458-
y: number,
1459-
deltaX: number,
1460-
deltaY: number,
1461-
options?: { returnXpath?: false },
1462-
): Promise<void>;
1463-
async scroll(
1464-
x: number,
1465-
y: number,
1466-
deltaX: number,
1467-
deltaY: number,
1468-
options: { returnXpath: boolean },
1469-
): Promise<void | string>;
14701413
@logAction("Page.scroll")
14711414
async scroll(
14721415
x: number,
14731416
y: number,
14741417
deltaX: number,
14751418
deltaY: number,
14761419
options?: { returnXpath?: boolean },
1477-
): Promise<void | string> {
1420+
): Promise<string> {
14781421
let xpathResult: string | undefined;
14791422
if (options?.returnXpath) {
14801423
try {
@@ -1503,49 +1446,13 @@ export class Page {
15031446
deltaY,
15041447
} as Protocol.Input.DispatchMouseEventRequest);
15051448

1506-
if (options?.returnXpath) return xpathResult ?? "";
1449+
return xpathResult ?? "";
15071450
}
15081451

15091452
/**
15101453
* Drag from (fromX, fromY) to (toX, toY) using mouse events.
15111454
* Sends mouseMoved → mousePressed → mouseMoved (steps) → mouseReleased.
15121455
*/
1513-
async dragAndDrop(
1514-
fromX: number,
1515-
fromY: number,
1516-
toX: number,
1517-
toY: number,
1518-
options: {
1519-
button?: "left" | "right" | "middle";
1520-
steps?: number;
1521-
delay?: number;
1522-
returnXpath: true;
1523-
},
1524-
): Promise<[string, string]>;
1525-
async dragAndDrop(
1526-
fromX: number,
1527-
fromY: number,
1528-
toX: number,
1529-
toY: number,
1530-
options?: {
1531-
button?: "left" | "right" | "middle";
1532-
steps?: number;
1533-
delay?: number;
1534-
returnXpath?: false;
1535-
},
1536-
): Promise<void>;
1537-
async dragAndDrop(
1538-
fromX: number,
1539-
fromY: number,
1540-
toX: number,
1541-
toY: number,
1542-
options: {
1543-
button?: "left" | "right" | "middle";
1544-
steps?: number;
1545-
delay?: number;
1546-
returnXpath: boolean;
1547-
},
1548-
): Promise<void | [string, string]>;
15491456
@logAction("Page.dragAndDrop")
15501457
async dragAndDrop(
15511458
fromX: number,
@@ -1558,7 +1465,7 @@ export class Page {
15581465
delay?: number;
15591466
returnXpath?: boolean;
15601467
},
1561-
): Promise<void | [string, string]> {
1468+
): Promise<[string, string]> {
15621469
const button = options?.button ?? "left";
15631470
const steps = Math.max(1, Math.floor(options?.steps ?? 1));
15641471
const delay = Math.max(0, options?.delay ?? 0);
@@ -1642,7 +1549,7 @@ export class Page {
16421549
clickCount: 1,
16431550
} as Protocol.Input.DispatchMouseEventRequest);
16441551

1645-
if (options?.returnXpath) return [fromXpath ?? "", toXpath ?? ""];
1552+
return [fromXpath ?? "", toXpath ?? ""];
16461553
}
16471554

16481555
/**

0 commit comments

Comments
 (0)