From b34bd2c86389405b24d8e710d81ab45097c73158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Simon=20Maria=20M=C3=B6llers?= Date: Mon, 18 Jun 2018 21:36:27 +0200 Subject: [PATCH] [puppeteer] Improve typings for $eval and $$eval - Require TypeScript Version 2.8 in puppeteer - Use conditional types to wrap or unwrap `ElementHandle` - Define an `Evalable` interface for `Page`, `Frame` and `ElementHandle` - Require TypeScript Version 2.8 in jest-environment-puppeteer - Require TypeScript Version 2.8 in expect-puppeteer - Require TypeScript Version 2.8 in storybook__addon-storyshots --- types/expect-puppeteer/index.d.ts | 2 +- types/jest-environment-puppeteer/index.d.ts | 2 +- types/puppeteer/index.d.ts | 230 +++++++++++++++---- types/puppeteer/puppeteer-tests.ts | 20 +- types/storybook__addon-storyshots/index.d.ts | 2 +- 5 files changed, 209 insertions(+), 47 deletions(-) diff --git a/types/expect-puppeteer/index.d.ts b/types/expect-puppeteer/index.d.ts index 4d599f99fe..24675ee695 100644 --- a/types/expect-puppeteer/index.d.ts +++ b/types/expect-puppeteer/index.d.ts @@ -2,7 +2,7 @@ // Project: https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer // Definitions by: Josh Goldberg // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.4 +// TypeScript Version: 2.8 /// diff --git a/types/jest-environment-puppeteer/index.d.ts b/types/jest-environment-puppeteer/index.d.ts index e22bee2f7d..79c25e32d8 100644 --- a/types/jest-environment-puppeteer/index.d.ts +++ b/types/jest-environment-puppeteer/index.d.ts @@ -2,7 +2,7 @@ // Project: https://github.com/smooth-code/jest-puppeteer/tree/master/packages/jest-environment-puppeteer // Definitions by: Josh Goldberg // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.3 +// TypeScript Version: 2.8 import { Browser, Page } from "puppeteer"; diff --git a/types/puppeteer/index.d.ts b/types/puppeteer/index.d.ts index ad12c17e99..32cab93ca5 100644 --- a/types/puppeteer/index.d.ts +++ b/types/puppeteer/index.d.ts @@ -4,13 +4,200 @@ // Christopher Deutsch // Konstantin Simon Maria Möllers // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.3 +// TypeScript Version: 2.8 /// import { EventEmitter } from "events"; import { ChildProcess } from "child_process"; +/** Wraps a DOM element into an ElementHandle instance */ +export type WrapElementHandle = X extends Element ? ElementHandle : X; + +/** Unwraps a DOM element out of an ElementHandle instance */ +export type UnwrapElementHandle = X extends ElementHandle ? E : X; + +/** Defines `$eval` and `$$eval` for Page, Frame and ElementHandle. */ +export interface Evalable { + /** + * This method runs `document.querySelector` within the context and passes it as the first argument to `pageFunction`. + * If there's no element matching `selector`, the method throws an error. + * + * If `pageFunction` returns a Promise, then `$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @returns Promise which resolves to the return value of pageFunction + */ + $eval( + selector: string, + pageFunction: (element: Element) => R | Promise, + ): Promise>; + + /** + * This method runs `document.querySelector` within the context and passes it as the first argument to `pageFunction`. + * If there's no element matching `selector`, the method throws an error. + * + * If `pageFunction` returns a Promise, then `$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @param x1 First argument to pass to pageFunction + * @returns Promise which resolves to the return value of pageFunction + */ + $eval( + selector: string, + pageFunction: (element: Element, x1: UnwrapElementHandle) => R | Promise, + x1: X1, + ): Promise>; + + /** + * This method runs `document.querySelector` within the context and passes it as the first argument to `pageFunction`. + * If there's no element matching `selector`, the method throws an error. + * + * If `pageFunction` returns a Promise, then `$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @param x1 First argument to pass to pageFunction + * @param x2 Second argument to pass to pageFunction + * @returns Promise which resolves to the return value of pageFunction + */ + $eval( + selector: string, + pageFunction: (element: Element, x1: UnwrapElementHandle, x2: UnwrapElementHandle) => R | Promise, + x1: X1, + x2: X2, + ): Promise>; + + /** + * This method runs `document.querySelector` within the context and passes it as the first argument to `pageFunction`. + * If there's no element matching `selector`, the method throws an error. + * + * If `pageFunction` returns a Promise, then `$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @param x1 First argument to pass to pageFunction + * @param x2 Second argument to pass to pageFunction + * @param x3 Third argument to pass to pageFunction + * @returns Promise which resolves to the return value of pageFunction + */ + $eval( + selector: string, + pageFunction: (element: Element, x1: UnwrapElementHandle, x2: UnwrapElementHandle, x3: UnwrapElementHandle) => R | Promise, + x1: X1, + x2: X2, + x3: X3, + ): Promise>; + + /** + * This method runs `document.querySelector` within the context and passes it as the first argument to `pageFunction`. + * If there's no element matching `selector`, the method throws an error. + * + * If `pageFunction` returns a Promise, then `$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @param args Arguments to pass to pageFunction + * @returns Promise which resolves to the return value of pageFunction + */ + $eval( + selector: string, + pageFunction: (element: Element, ...args: any[]) => R | Promise, + ...args: any[], + ): Promise>; + + /** + * This method runs `Array.from(document.querySelectorAll(selector))` within the context and passes it as the + * first argument to `pageFunction`. + * + * If `pageFunction` returns a Promise, then `$$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @returns Promise which resolves to the return value of pageFunction + */ + $$eval( + selector: string, + pageFunction: (elements: Element[]) => R | Promise, + ): Promise>; + + /** + * This method runs `Array.from(document.querySelectorAll(selector))` within the context and passes it as the + * first argument to `pageFunction`. + * + * If `pageFunction` returns a Promise, then `$$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @param x1 First argument to pass to pageFunction + * @returns Promise which resolves to the return value of pageFunction + */ + $$eval( + selector: string, + pageFunction: (elements: Element[], x1: UnwrapElementHandle) => R | Promise, + x1: X1, + ): Promise>; + + /** + * This method runs `Array.from(document.querySelectorAll(selector))` within the context and passes it as the + * first argument to `pageFunction`. + * + * If `pageFunction` returns a Promise, then `$$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @param x1 First argument to pass to pageFunction + * @param x2 Second argument to pass to pageFunction + * @returns Promise which resolves to the return value of pageFunction + */ + $$eval( + selector: string, + pageFunction: (elements: Element[], x1: UnwrapElementHandle, x2: UnwrapElementHandle) => R | Promise, + x1: X1, + x2: X2, + ): Promise>; + + /** + * This method runs `Array.from(document.querySelectorAll(selector))` within the context and passes it as the + * first argument to `pageFunction`. + * + * If `pageFunction` returns a Promise, then `$$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @param x1 First argument to pass to pageFunction + * @param x2 Second argument to pass to pageFunction + * @param x3 Third argument to pass to pageFunction + * @returns Promise which resolves to the return value of pageFunction + */ + $$eval( + selector: string, + pageFunction: (elements: Element[], x1: UnwrapElementHandle, x2: UnwrapElementHandle, x3: UnwrapElementHandle) => R | Promise, + x1: X1, + x2: X2, + x3: X3, + ): Promise>; + + /** + * This method runs `Array.from(document.querySelectorAll(selector))` within the context and passes it as the + * first argument to `pageFunction`. + * + * If `pageFunction` returns a Promise, then `$$eval` would wait for the promise to resolve and return its value. + * + * @param selector A selector to query for + * @param pageFunction Function to be evaluated in browser context + * @param args Arguments to pass to pageFunction + * @returns Promise which resolves to the return value of pageFunction + */ + $$eval( + selector: string, + pageFunction: (elements: Element[], ...args: any[]) => R | Promise, + ...args: any[] + ): Promise>; +} + /** Keyboard provides an api for managing a virtual keyboard. */ export interface Keyboard { /** @@ -485,7 +672,7 @@ export interface Worker { /** * Represents an in-page DOM element. ElementHandles can be created with the page.$ method. */ -export interface ElementHandle extends JSHandle { +export interface ElementHandle extends JSHandle, Evalable { /** * The method runs element.querySelector within the page. * If no element matches the selector, the return value resolve to null. @@ -502,18 +689,6 @@ export interface ElementHandle extends JSHandle { */ $$(selector: string): Promise; - /** - * This method runs `document.querySelector` within the element and passes it as the first argument to `pageFunction`. - * If there's no element matching `selector`, the method throws an error. - * - * If `pageFunction` returns a Promise, then `frame.$eval` would wait for the promise to resolve and return its value. - */ - $eval( - selector: string, - pageFunction: (element: Element, ...args: any[]) => T, - ...args: any[] - ): Promise; - /** * @param selector XPath expression to evaluate. */ @@ -811,7 +986,7 @@ export interface Response { url(): string; } -export interface FrameBase { +export interface FrameBase extends Evalable { /** * The method queries frame for the selector. * If there's no such element within the frame, the method will resolve to null. @@ -830,31 +1005,6 @@ export interface FrameBase { */ $x(expression: string): Promise; - /** - * This method runs document.querySelector within the page and passes it as the first argument to `fn`. - * If there's no element matching selector, the method throws an error. - * If `pageFunction` returns a Promise, then $eval would wait for the promise to resolve and return its value. - */ - $eval( - selector: string, - pageFunction: (element: Element, ...args: any[]) => T, - ...args: any[] - ): Promise; - - /** - * This method runs document.querySelectorAll within the frame and passes it as the first argument to pageFunction. - * If pageFunction returns a Promise, then frame.$$eval would wait for the promise to resolve and return its value. - * @param selector A selector to query frame for - * @param fn Function to be evaluated in browser context - * @param args Arguments to pass to pageFunction - * @returns Promise which resolves to the return value of pageFunction - */ - $$eval( - selector: string, - pageFunction: (elements: NodeListOf, ...args: any[]) => T, - ...args: any[] - ): Promise; - /** Adds a `