From dfb1f2ac9914fb5d279a74b7a0224f8de62e87f0 Mon Sep 17 00:00:00 2001 From: lino-levan <11367844+lino-levan@users.noreply.github.com> Date: Tue, 22 Aug 2023 11:16:09 -0700 Subject: [PATCH] feat: allow passing args to evaluate --- docs/pages/examples/evaluate.md | 41 +++++++++++++++++++++++++++++++++ examples/evaluate.ts | 8 +++++++ src/page.ts | 27 ++++++++++++++++++---- tests/evaluate_test.ts | 21 +++++++++++++++++ 4 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 docs/pages/examples/evaluate.md create mode 100644 tests/evaluate_test.ts diff --git a/docs/pages/examples/evaluate.md b/docs/pages/examples/evaluate.md new file mode 100644 index 0000000..44f888a --- /dev/null +++ b/docs/pages/examples/evaluate.md @@ -0,0 +1,41 @@ +--- +title: 2.3 - Evaluate +description: A small example on how to do complex evaluation in Astral +index: 1 +--- + +## Running + +```bash +deno run -A https://deno.land/x/astral/examples/evaluate.ts +``` + +## Code + +```ts +// Import Astral +import { launch } from "https://deno.land/x/astral/mod.ts"; + +// Launch the browser +const browser = await launch(); + +// Open a new page +const page = await browser.newPage("https://deno.land"); + +// Run code in the context of the browser +const value = await page.evaluate(() => { + return document.body.innerHTML; +}); +console.log(value); + +// Run code with args +const result = await page.evaluate((x, y) => { + return `The result of adding ${x}+${y} = ${x + y}`; +}, { + args: [10, 15], +}); +console.log(result); + +// Close the browser +await browser.close(); +``` diff --git a/examples/evaluate.ts b/examples/evaluate.ts index 81180ab..e37da08 100644 --- a/examples/evaluate.ts +++ b/examples/evaluate.ts @@ -15,5 +15,13 @@ const value = await page.evaluate(() => { }); console.log(value); +// Run code with args +const result = await page.evaluate((x, y) => { + return `The result of adding ${x}+${y} = ${x + y}`; +}, { + args: [10, 15], +}); +console.log(result); + // Close the browser await browser.close(); diff --git a/src/page.ts b/src/page.ts index ebbe3c3..633e469 100644 --- a/src/page.ts +++ b/src/page.ts @@ -37,7 +37,15 @@ export type WaitForNetworkIdleOptions = { idleConnections?: number; }; -export type EvalFunc = string | (() => T); +type AnyArray = readonly unknown[]; + +export type EvaluateFunction = + | string + | ((...args: R) => T); + +export interface EvaluateOptions { + args: Readonly; +} /** * Page provides methods to interact with a single tab in the browser @@ -207,9 +215,15 @@ export class Page { * const innerHTML = await page.evaluate(()=>document.body.innerHTML) * ``` */ - async evaluate(func: EvalFunc) { + async evaluate( + func: EvaluateFunction, + evaluateOptions?: EvaluateOptions, + ) { if (typeof func === "function") { - func = `(${func.toString()})()`; + const args = evaluateOptions?.args ?? []; + func = `(${func.toString()})(${ + args.map((arg) => `${JSON.stringify(arg)}`).join(",") + })`; } const { result, exceptionDetails } = await retryDeadline( this.#celestial.Runtime.evaluate({ @@ -319,12 +333,15 @@ export class Page { /** * Runs a function in the context of the page until it returns a truthy value. */ - async waitForFunction(func: EvalFunc) { + async waitForFunction( + func: EvaluateFunction, + evaluateOptions?: EvaluateOptions, + ) { // TODO(lino-levan): Make this easier to read await deadline( (async () => { while (true) { - const result = await this.evaluate(func); + const result = await this.evaluate(func, evaluateOptions); if (result) { return result; diff --git a/tests/evaluate_test.ts b/tests/evaluate_test.ts new file mode 100644 index 0000000..e8f8257 --- /dev/null +++ b/tests/evaluate_test.ts @@ -0,0 +1,21 @@ +import { assertEquals } from "https://deno.land/std@0.198.0/assert/assert_equals.ts"; +import { launch } from "../mod.ts"; + +Deno.test("Testing evaluate", async () => { + // Launch browser + const browser = await launch(); + + // Open the webpage + const page = await browser.newPage("http://example.com"); + + // passing arguments to evaluate + const result = await page.evaluate((x, y) => { + return x + y; + }, { + args: ["string", "concat"] as const, + }); + assertEquals(result, "stringconcat"); + + // Close browser + await browser.close(); +});