| ... | @@ -277,3 +277,45 @@ describe("server browser element refs", () => { | ... | @@ -277,3 +277,45 @@ describe("server browser element refs", () => { |
| 277 | expect(await ServerBrowserPage.evaluate(cdp, { expression: "1 + 1" }, 2_000)).toBe(2); | 277 | expect(await ServerBrowserPage.evaluate(cdp, { expression: "1 + 1" }, 2_000)).toBe(2); |
| 278 | }); | 278 | }); |
| 279 | }); | 279 | }); |
| | 280 | |
| | 281 | describe("server browser drag", () => { |
| | 282 | it("fails the drag, not the server, when it times out while the cursor is still moving", async () => { |
| | 283 | const timedOut = new Error("locator.dragTo: Timeout 30000ms exceeded."); |
| | 284 | const box = { x: 0, y: 0, width: 20, height: 20 }; |
| | 285 | const targetBox = Promise.withResolvers<typeof box>(); |
| | 286 | // Only the calls `drag` makes. The drag fails at once; the target's position arrives only |
| | 287 | // when the test hands it over, after the rejection has had a turn to go unobserved. |
| | 288 | const page = { |
| | 289 | locator: (selector: string) => |
| | 290 | selector === "#card" |
| | 291 | ? { |
| | 292 | scrollIntoViewIfNeeded: async () => {}, |
| | 293 | boundingBox: async () => box, |
| | 294 | dragTo: () => Promise.reject(timedOut), |
| | 295 | } |
| | 296 | : { boundingBox: () => targetBox.promise }, |
| | 297 | } as unknown as Page; |
| | 298 | const unobserved: Array<unknown> = []; |
| | 299 | const onUnhandled = (reason: unknown) => unobserved.push(reason); |
| | 300 | process.on("unhandledRejection", onUnhandled); |
| | 301 | try { |
| | 302 | let finished = false; |
| | 303 | const settled = ServerBrowserPage.drag(page, { source: "#card", target: "#lane" }).then( |
| | 304 | () => null, |
| | 305 | (error: unknown) => error, |
| | 306 | ); |
| | 307 | void settled.then(() => (finished = true)); |
| | 308 | // Two macrotask turns: Node reports a rejection nobody observed after the first. |
| | 309 | await new Promise((resolve) => setImmediate(resolve)); |
| | 310 | await new Promise((resolve) => setImmediate(resolve)); |
| | 311 | // The failed drag waits for the cursor to reach the target before it reports. |
| | 312 | expect(finished).toBe(false); |
| | 313 | targetBox.resolve(box); |
| | 314 | |
| | 315 | expect(await settled).toBe(timedOut); |
| | 316 | expect(unobserved).toEqual([]); |
| | 317 | } finally { |
| | 318 | process.off("unhandledRejection", onUnhandled); |
| | 319 | } |
| | 320 | }); |
| | 321 | }); |