From a1bbbc2c942943f4bc02a5d718dbfe084179f1b5 Mon Sep 17 00:00:00 2001 From: lino-levan <11367844+lino-levan@users.noreply.github.com> Date: Wed, 16 Aug 2023 10:13:51 -0700 Subject: [PATCH] feat: support --- src/page.ts | 25 ++++++++++++++++++++++++- tests/__snapshots__/wait_test.ts.snap | 3 +++ tests/wait_test.ts | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/__snapshots__/wait_test.ts.snap diff --git a/src/page.ts b/src/page.ts index edbabf6..eecc42b 100644 --- a/src/page.ts +++ b/src/page.ts @@ -1,3 +1,5 @@ +import { deadline } from "https://deno.land/std@0.198.0/async/deadline.ts"; + import { Celestial, Network_Cookie } from "../bindings/celestial.ts"; import { Browser } from "./browser.ts"; import { ElementHandle } from "./elementHandle.ts"; @@ -35,6 +37,8 @@ export type WaitForNetworkIdleOptions = { idleConnections?: number; }; +export type EvalFunc = string | (() => T); + export class Page { #id: string; #celestial: Celestial; @@ -193,7 +197,7 @@ export class Page { * const innerHTML = await page.evaluate(()=>document.body.innerHTML) * ``` */ - async evaluate(func: string | (() => T)) { + async evaluate(func: EvalFunc) { if (typeof func === "function") { func = `(${func.toString()})()`; } @@ -302,6 +306,25 @@ export class Page { return convertToUint8Array(data); } + /** + * Runs a function in the context of the page until it returns a truthy value. + */ + async waitForFunction(func: EvalFunc) { + // TODO(lino-levan): Make this easier to read + await deadline( + (async () => { + while (true) { + const result = await this.evaluate(func); + + if (result) { + return result; + } + } + })(), + this.timeout, + ); + } + /** * Waits for the page to navigate to a new URL or to reload. It is useful when you run code that will indirectly cause the page to navigate. */ diff --git a/tests/__snapshots__/wait_test.ts.snap b/tests/__snapshots__/wait_test.ts.snap new file mode 100644 index 0000000..ab5eef3 --- /dev/null +++ b/tests/__snapshots__/wait_test.ts.snap @@ -0,0 +1,3 @@ +export const snapshot = {}; + +snapshot[`Wait for function 1`] = `undefined`; diff --git a/tests/wait_test.ts b/tests/wait_test.ts index 307d974..20b6683 100644 --- a/tests/wait_test.ts +++ b/tests/wait_test.ts @@ -1,3 +1,4 @@ +import { assertSnapshot } from "https://deno.land/std@0.198.0/testing/snapshot.ts"; import { launch } from "../mod.ts"; Deno.test("Wait for selector", async () => { @@ -14,3 +15,21 @@ Deno.test("Wait for selector", async () => { // Close browser await browser.close(); }); + +Deno.test("Wait for function", async (t) => { + // Launch browser + const browser = await launch(); + + // Open the webpage + const page = await browser.newPage("https://pyro.deno.dev"); + + // Wait for function (kind of a stupid case, but whatever, make it better if you see this) + const fetched = await page.waitForFunction(async () => { + const req = await fetch("https://pyro.deno.dev/guides/"); + return await req.text(); + }); + assertSnapshot(t, fetched); + + // Close browser + await browser.close(); +});