Skip to content

Commit

Permalink
test: enable runner test
Browse files Browse the repository at this point in the history
  • Loading branch information
OrKoN committed Feb 3, 2022
1 parent 1860924 commit 1b7818a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 31 deletions.
68 changes: 41 additions & 27 deletions src/PuppeteerRunnerExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,16 @@ export class PuppeteerRunnerExtension implements RunnerExtension {
});
await scrollIntoViewIfNeeded(element, timeout);
const inputType = await element.evaluate(
(el) => (el as HTMLInputElement).type
(el: Element) => (el as HTMLInputElement).type
);
if (typeableInputTypes.has(inputType)) {
await element.evaluate((el) => {
await element.evaluate((el: Element) => {
(el as HTMLInputElement).value = "";
});
await element.type(step.value);
} else {
await element.focus();
await element.evaluate((el, value) => {
await element.evaluate((el: Element, value: string) => {
const input = el as HTMLInputElement;
input.value = value;
input.dispatchEvent(new Event("input", { bubbles: true }));
Expand All @@ -142,7 +142,7 @@ export class PuppeteerRunnerExtension implements RunnerExtension {
});
await scrollIntoViewIfNeeded(element, timeout);
await element.evaluate(
(e, x, y) => {
(e: Element, x: number, y: number) => {
e.scrollTop = y;
e.scrollLeft = x;
},
Expand Down Expand Up @@ -287,7 +287,7 @@ async function scrollIntoViewIfNeeded(
if (isInViewport) {
return;
}
await element.evaluate((element) => {
await element.evaluate((element: Element) => {
element.scrollIntoView({
block: "center",
inline: "center",
Expand All @@ -302,7 +302,7 @@ async function waitForConnected(
timeout: number
): Promise<void> {
await waitForFunction(async () => {
return await element.evaluate((el) => el.isConnected);
return await element.evaluate((el: Element) => el.isConnected);
}, timeout);
}

Expand Down Expand Up @@ -366,7 +366,7 @@ async function waitForSelector(
// if not the last part, try to navigate into shadowRoot
const oldElement = element;
element = (
await element.evaluateHandle((el) =>
await element.evaluateHandle((el: Element) =>
el.shadowRoot ? el.shadowRoot : el
)
).asElement();
Expand Down Expand Up @@ -423,7 +423,9 @@ async function querySelectorAll(
// if not the last part, try to navigate into shadowRoot
for (const el of elements) {
const newEl = (
await el.evaluateHandle((el) => (el.shadowRoot ? el.shadowRoot : el))
await el.evaluateHandle((el: Element) =>
el.shadowRoot ? el.shadowRoot : el
)
).asElement();
if (newEl) {
tmpElements.push(newEl);
Expand Down Expand Up @@ -454,15 +456,13 @@ async function waitForFunction(
throw new Error("Timed out");
}


// Partial description of Puppeteer API below to allow runtime dependencies.
type EvaluateFn<T = any> = string | ((arg1: T, ...args: any[]) => any);
type EvaluateFnReturnType<T extends EvaluateFn> = T extends (
...args: any[]
) => infer R
? R
: any;
type EvaluateHandleFn = string | ((...args: any[]) => any);
type SerializableOrJSHandle = Serializable | JSHandle;
type JSONArray = readonly Serializable[];
interface JSONObject {
Expand All @@ -480,29 +480,35 @@ type UnwrapPromiseLike<T> = T extends PromiseLike<infer U> ? U : T;

interface Target {
url(): string;
page(): Promise<Page|null>;
page(): Promise<Page | null>;
}

export interface WaitForTargetOptions {
/**
* Maximum wait time in milliseconds. Pass `0` to disable the timeout.
* @defaultValue 30 seconds.
*/
timeout?: number;
}

interface Browser {
waitForTarget(
fn: (t: Target) => boolean,
opts?: { timeout: number }
predicate: (x: Target) => boolean,
options?: WaitForTargetOptions
): Promise<Target>;
}

interface JSHandle<HandleObjectType = unknown> {
// TODO: fix the type of evaluate.
evaluate<T extends EvaluateFn<HandleObjectType>>(
pageFunction: T | string,
...args: SerializableOrJSHandle[]
...args: any[]
): Promise<UnwrapPromiseLike<EvaluateFnReturnType<T>>>;
evaluateHandle<HandleType extends ElementHandle = ElementHandle>(
pageFunction: EvaluateHandleFn,
...args: SerializableOrJSHandle[]
): Promise<HandleType>;
asElement(): ElementHandle | null;
// TODO: fix the type of evaluateHandle.
evaluateHandle(...args: any[]): Promise<JSHandle<Element>>;
asElement(): ElementHandle<Element> | null;
}

interface ElementHandle<ElementType extends Element = Element>
interface ElementHandle<ElementType extends Element>
extends JSHandle<ElementType> {
isIntersectingViewport(opts: { threshold: number }): Promise<boolean>;
dispose(): Promise<void>;
Expand All @@ -518,9 +524,13 @@ interface ElementHandle<ElementType extends Element = Element>
selector: string
): Promise<Array<ElementHandle<T>>>;
waitForSelector(
part: string,
options: WaitForOptions
): Promise<ElementHandle<Element>>;
selector: string,
options?: {
visible?: boolean;
hidden?: boolean;
timeout?: number;
}
): Promise<ElementHandle<Element> | null>;
asElement(): ElementHandle<ElementType> | null;
}

Expand All @@ -538,14 +548,16 @@ interface Page {
setViewport(viewport: any): Promise<void>;
mainFrame(): Frame;
waitForNavigation(opts: { timeout: number }): Promise<unknown>;
$$(selector: string): Promise<Array<ElementHandle<Element>>>;
$$<T extends Element = Element>(
selector: string
): Promise<Array<ElementHandle<T>>>;
}

interface Frame {
waitForSelector(
part: string,
options: WaitForOptions
): Promise<ElementHandle<Element>|null>;
): Promise<ElementHandle<Element> | null>;
isOOPFrame(): boolean;
url(): string;
evaluate<T extends EvaluateFn>(
Expand All @@ -556,5 +568,7 @@ interface Frame {
waitForFunction(expr: string, opts: { timeout: number }): Promise<unknown>;
childFrames(): Frame[];
waitForNavigation(opts: { timeout: number }): Promise<unknown>;
$$(selector: string): Promise<Array<ElementHandle<Element>>>;
$$<T extends Element = Element>(
selector: string
): Promise<Array<ElementHandle<T>>>;
}
14 changes: 13 additions & 1 deletion src/Runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
limitations under the License.
*/

import { PuppeteerRunnerExtension } from "./PuppeteerRunnerExtension.js";
import { RunnerExtension } from "./RunnerExtension.js";
import { UserFlow } from "./Schema.js";

Expand Down Expand Up @@ -57,6 +58,17 @@ export class Runner {
}
}

export function createRunner(flow: UserFlow, extension: RunnerExtension) {
export async function createRunner(
flow: UserFlow,
extension?: RunnerExtension
) {
if (!extension) {
const puppeteer = await import("puppeteer");
const browser = await puppeteer.launch({
headless: true,
});
const page = await browser.newPage();
extension = new PuppeteerRunnerExtension(browser, page);
}
return new Runner(flow, extension);
}
5 changes: 2 additions & 3 deletions test/runner_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import { createRunner } from "../src/Runner.js";
import { PuppeteerRunnerExtension } from "../src/PuppeteerRunnerExtension.js";
import puppeteer from "puppeteer";

// TODO: the test is passing locally but skipping it until CI is setup in follow-ups.
describe.skip("Runner", () => {
describe("Runner", () => {
let browser: puppeteer.Browser;
let page: puppeteer.Page;

Expand All @@ -42,7 +41,7 @@ describe.skip("Runner", () => {
});

it("should run an empty flow using Puppeteer", async () => {
const runner = createRunner(
const runner = await createRunner(
{
title: "test",
steps: [],
Expand Down

0 comments on commit 1b7818a

Please sign in to comment.