import type { Locator, Page } from "playwright-core"; import { extractMarkdownFromPage, extractStructuredDataFromPage, } from "../ai-extractors"; import { extractArrayFromPage, extractObjectFromPage, } from "../optimized-extractors"; /** * Navigates to a specified URL on the provided playwright page. * * @param {Page} page - The Playwright page object to navigate. * @param {string} url - The URL to navigate to. * @param {string} [options.referer] - Referer header value. If provided, it will take preference over the referer header value set by `page.setExtraHTTPHeaders(headers)`. * @param {number} [options.timeout=0] - Maximum operation time in milliseconds. Defaults to `0` (no timeout). This can be configured via various timeout settings on the page or browser context. * @param {"load"|"domcontentloaded"|"networkidle"|"commit"} [options.waitUntil="networkidle"] - When to consider the operation succeeded. Defaults to `networkidle` (playwright default to `load`). * @param {boolean} [options.throwOnTimeout=false] - Whether to throw if the `page.goto` times out. By default, it ignores the error. * @returns {Promise} - A promise that resolves to the response of the navigation, or null if no response was received. * * @example * ```typescript without options * import { goto } from "@intuned/sdk/playwright"; * * await goto(page, 'https://example.com'); * * ``` * * ```typescript with options * import { goto } from "@intuned/sdk/playwright"; * * await goto(page, 'https://example.com', { * waitUntil: "load", * throwOnTimeout: true, * timeout: 10_000 * }); * ``` */ export declare function goto( page: Page, url: string, options?: { referer?: string; timeout?: number; waitUntil?: "load" | "domcontentloaded" | "networkidle" | "commit"; throwOnTimeout?: boolean; } ): ReturnType; export interface ExtendedPlaywrightPage extends Page { /** * * an alias for [extractStructuredDataFromPage](/automation-sdks/runtime-sdk/ai-extractors/functions/extractStructuredDataFromPage) function * */ goto: ( url: string, options?: { referer?: string; timeout?: number; waitUntil?: "load" | "domcontentloaded" | "networkidle" | "commit"; throwOnTimeout?: boolean; } ) => ReturnType; /** * * an alias for [extractStructuredDataFromPage](/automation-sdks/runtime-sdk/ai-extractors/functions/extractStructuredDataFromPage) function * */ extractStructuredData: ( options: Parameters[1] ) => ReturnType; /** * * an alias for [extractMarkdownFromPage](/automation-sdks/runtime-sdk/ai-extractors/functions/extractMarkdownFromPage) function * */ extractMarkdown: () => ReturnType; /** * * an alias for [extractArrayFromPage](/automation-sdks/runtime-sdk/optimized-extractors/functions/extractArrayFromPage) function * */ extractArrayOptimized: ( options: Parameters[1] ) => ReturnType; /** * * an alias for [extractObjectFromPage](/automation-sdks/runtime-sdk/optimized-extractors/functions/extractObjectFromPage) function * */ extractObjectOptimized: ( options: Parameters[1] ) => ReturnType; /** * * an alias for [fillForm](/automation-sdks/runtime-sdk/playwright/functions/fillForm) function * */ fillForm: ( options: Parameters[1] ) => ReturnType; /** * * an alias for [extractArrayFromPageUsingSelectors](/automation-sdks/runtime-sdk/playwright/functions/extractArrayFromPageUsingSelectors) function * */ extractArrayUsingSelectors: ( extractor: T ) => Promise>; /** * * an alias for [extractObjectFromPageUsingSelectors](/automation-sdks/runtime-sdk/playwright/functions/extractObjectFromPageUsingSelectors) function * */ extractObjectUsingSelectors: ( extractor: T ) => Promise>; } /** * Extends a Playwright Page with additional functionalities from intuned, like ai powered data extraction and and actions helpers like fillform. * * @param page - The Playwright Page to extend. * @returns An extended Page with additional functionalities. * * @example * ```typescript extendPlaywrightPage * import { BrowserContext, Page } from "playwright-core"; * import { extendPlaywrightPage } from "@intuned/sdk/playwright"; * * interface Params { * // Add your params here * } * * export default async function handler( * params: Params, * _playwrightPage: Page, * context: BrowserContext * ) { * const page = extendPlaywrightPage(_playwrightPage); * const pageMarkdown = await page.extractMarkdown() * * return pageMarkdown * } * ``` */ export declare function extendPlaywrightPage( page: Page ): ExtendedPlaywrightPage; /** * -- * @interface * @property selector - The selector string for the element. * @property [type] - Optional. The type of the selector (xpath or css) default is `css` */ export interface ElementSelector { selector: string; type?: "xpath" | "css"; } type InputFieldType = | "text-input" | "select" | "checkbox" | "radiogroup" | "submit-button" | "auto-complete"; /** * -- * @interface * @property fieldSelector - The selector for the form field. * @property fieldType - The type of the input field, supported types are: `text-input` `select` `checkbox` `radiogroup` `submit-button` `auto-complete` * @property value * @property value.type - "dynamic" which means that intuned will use ai to figure out the correct field value. * @property value.source - the data to be used by the ai to fill the field, it can be a string or an object. */ export interface DynamicFormInputItem { fieldSelector: ElementSelector; fieldType: InputFieldType; value: { type: "dynamic"; source: string | object; }; } /** * -- * @interface * @property fieldSelector - The selector for the form field. * @property fieldType - The type of the input field, supported types are: `text-input` `select` `checkbox` `radiogroup` `submit-button` `auto-complete` * @property value * @property value.type - The type of the value, which is always "static". * @property value.value - The static value to be filled (string, boolean, or number). */ export interface StaticFormInputItem { fieldSelector: ElementSelector; fieldType: InputFieldType; value: { type: "static"; value: string | boolean | number; }; } export type FormInputItem = DynamicFormInputItem | StaticFormInputItem; /** * Fills a form on a web page with specified inputs and submits the form. the function handles static data, and can derive data using ai using your input. * the function has the ability to detect form submission errors and use ai to recover from these errors. * * @param page - The Playwright Page where the form is located. * @param options.formLocator - The locator for the form element. * @param options.formInput - An array of form input items (dynamic or static). * @param options.submitForm - A function to submit the form. * @param options.isSubmitSuccessful - A function to check if the form submission was successful. * @param options.autoRecoveryOptions - Optional. Options for auto-recovery in case of form submission failure. * @param options.timeout - Optional. Timeout for the entire form filling process. * @param options.fillFieldTimeout - Optional. Timeout for filling each individual field. * @param options.waitTimeBetweenFill - Optional. Wait time between filling each field. * @returns A promise that resolves to a boolean indicating whether the form submission was successful. * * @example * ```typescript fillForm * import { BrowserContext, Locator, Page } from "playwright-core"; * import { FormInputItem, extendPlaywrightPage } from "@intuned/sdk/playwright"; * * export interface Input { * firstName: string; * lastName: string; * address1: string; * address2: string; * city: string; * state: string; * zip: string; * country: string; * nameOnCard: string; * cardNumber: string; * expiration: string; * cvv: string; * saveAddress: boolean; * } * * export default async function handler( * params: Input, * _playwrightPage: Page, * context: BrowserContext * ) { * * const page = extendPlaywrightPage(_playwrightPage); * await page.goto("https://demo-site-eta.vercel.app/steps-form/ShippingAddress"); * * const fields: FormInputItem[] = [ * { * fieldSelector: { * selector: "[name='firstName']", * type: "css", * }, * value: { type: "static", value: params.firstName }, * fieldType: "text-input", * }, * { * fieldSelector: { * selector: "[name='lastName']", * type: "css", * }, * value: { type: "static", value: params.lastName }, * fieldType: "text-input", * }, * { * fieldSelector: { * selector: "[name='addressLine1']", * type: "css", * }, * value: { type: "static", value: params.address1 }, * fieldType: "text-input", * }, * { * fieldSelector: { * selector: "[name='addressLine2']", * type: "css", * }, * value: { type: "static", value: params.address2 }, * fieldType: "text-input", * }, * { * fieldSelector: { * selector: "[name='city']", * type: "css", * }, * value: { type: "static", value: params.city }, * fieldType: "text-input", * }, * { * fieldSelector: { * selector: "[name='state']", * type: "css", * }, * value: { type: "static", value: params.state }, * fieldType: "text-input", * }, * { * fieldSelector: { * selector: "[name='zipCode']", * type: "css", * }, * value: { type: "static", value: params.zip }, * fieldType: "text-input", * }, * { * fieldSelector: { * selector: "[name='country']", * type: "css", * }, * value: { type: "dynamic", source: { country: params.country } }, * fieldType: "select", * }, * { * fieldSelector: { * selector: "[name='futurePurchase']", * type: "css", * }, * fieldType: "checkbox", * value: { type: "static", value: true }, * }, * ]; * * const didFormSucceed = async (locator: Locator): Promise => { * return (await locator.page().locator(".error-message").count()) === 0 * }; * * * async function formSubmit(locator: Locator) { * const nextButtonLocator = locator.page().getByRole("button", { name: "Next" }); * await nextButtonLocator.waitFor({ state: "visible" }); * await nextButtonLocator.click(); * } * * await page.fillForm({ * formLocator: page.locator("main"), * formInput: fields, * isSubmitSuccessful: didFormSucceed, * submitForm: formSubmit, * autoRecoveryOptions: { * enabled: true, * recoveryData: params * } * }); * * return {}; * } * ``` */ export declare function fillForm( page: Page, options: { formLocator: ElementSelector | Locator; formInput: (DynamicFormInputItem | StaticFormInputItem)[]; submitForm: (formLocator: Locator) => Promise; isSubmitSuccessful: (formLocator: Locator) => Promise; autoRecoveryOptions?: { /** * Whether auto-recovery is enabled */ enabled: boolean; /** * Data to use for auto-recovery */ recoveryData: object; /** * Fields to mask during auto-recovery, use this if you do not want to send your form values to ai. */ fieldsToMask?: ElementSelector[]; /** * Maximum number of retries for auto-recovery */ maxRetries?: number; generateDataToUnblockForm?: { /** * Whether generating data to unblock the form is enabled. */ enabled: boolean; /** * The prompt to use for generating data. */ prompt: string; }; }; timeout?: number; fillFieldTimeout?: number; waitTimeBetweenFill?: number; } ): Promise; /** * a record or property name and the value selector to extract the value from the page. * you can provide a list of `ValueSelector` to provide a backup selector in case the first one fails. * the primary selector is the first one in the list. */ export type ObjectExtractor = Record; /** * -- * @interface * @property selector - The selector string for the element. * @property [type] - Optional. The type of the selector (xpath or css). default to `css` */ export interface ElementSelector { selector: string; type?: "xpath" | "css"; } /** * represents a dom element selector and the method to extract the value from the element. * * @interface * @extends ElementSelector * @property [selectionMethod] - Optional. The method for selecting the value. `all-text` selects all text content, `direct-text` selects the direct text content(does not include the text inside nested elements), and `propertyName` selects the value of a property. * @property [regex] - Optional. A regex pattern and match index for extracting the value. * @property [multiValue] - Optional. Whether the selector extracts multiple values, if set to true the returned value will be array of strings */ export interface ValueSelector extends ElementSelector { selectionMethod?: | "direct-text" | "all-text" | { propertyName: string; }; regex?: { pattern: string; matchIndex?: number; }; multiValue?: boolean; } /** * -- * * @interface * @property containerSelector - The selector(s) for the container elements of the list, all list items should be direct children of this container. * @property propertySelectors - The selectors for the properties to extract. the values of the selector should be relative to the list item. * * **example:** if the list was: * * ```html *
    *
  • *
    title 1
    *
    price 1
    *
  • *
  • *
    title 2
    *
    price 2
    *
  • *
* ``` * the css relative selectors should be: * * title -> `.title` * * price -> `.price` * */ export interface ListStaticExtractor { containerSelector: ElementSelector | ElementSelector[]; propertySelectors: Record; } export type ExtractObjectFromPageUsingSelectorsReturnType< T extends ObjectExtractor > = { [K in keyof T]: T[K] extends { multiValue: true; } ? string[] | null : string | null; }; export type ExtractListObjectsUsingStaticSelectorsReturnType< T extends ListStaticExtractor > = { [K in keyof T["propertySelectors"]]: T["propertySelectors"][K] extends { multiValue: true; } ? string[] | null : string | null; }[]; /** * Extracts an object from a web page using the specified selectors. * * @param page - The Playwright Page object from which to extract the data. * @param extractor - The object extractor with the selectors to use. * @returns A promise that resolves to the extracted object. * * @example * ```typescript extractObjectFromPageUsingSelectors * import { extractObjectFromPageUsingSelectors, goto } from "@intuned/sdk/playwright"; * * await goto(page, 'https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html'); * const book = await extractObjectFromPageUsingSelectors(page, { * name: { * selector: "h1", * selectionMethod: "all-text" * }, * inStock: { * selector: ".price_color", * }, * imgUrl: { * selector: "#product_gallery > div > div > div > img", * selectionMethod: { * propertyName: "src" * } * } * }) * * console.log(book) * * // output: * // { * // name: 'A Light in the Attic', * // inStock: '£51.77', * // imgUrl: '../../media/cache/fe/72/fe72f0532301ec28892ae79a629a293c.jpg' * // } * * ``` */ export declare function extractObjectFromPageUsingSelectors< T extends ObjectExtractor >( page: Page, extractor: T ): Promise>; /** * Extracts a list of objects from a web page using the specified static selectors. * * @param page - The Playwright Page object from which to extract the data. * @param listExtractor - The list static extractor with the selectors to use. * @returns A promise that resolves to the extracted list of objects. * @example * ```typescript extractArrayFromPageUsingSelectors * import { extractArrayFromPageUsingSelectors, goto } from "@intuned/sdk/playwright"; * * await goto(page, 'https://books.toscrape.com/index.html'); * const books = await extractArrayFromPageUsingSelectors(page, { * containerSelector: { * selector: '//*[@id="default"]/div/div/div/div/section/div[2]/ol', * type: "xpath" * }, * propertySelectors: { * name: { * selector: "h3", * }, * inStock: { * selector: ".price_color", * }, * imgUrl: { * selector: "article > div.image_container > a > img", * selectionMethod: { * propertyName: "src" * } * } * } * }) * * console.log(books) * * // output: * // [ * // { * // name: 'A Light in the ...', * // inStock: '£51.77', * // imgUrl: 'media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg' * // }, * // { * // name: 'Tipping the Velvet', * // inStock: '£53.74', * // imgUrl: 'media/cache/26/0c/260c6ae16bce31c8f8c95daddd9f4a1c.jpg' * // }, * // { * // name: 'Soumission', * // inStock: '£50.10', * // imgUrl: 'media/cache/3e/ef/3eef99c9d9adef34639f510662022830.jpg' * // }, * // { * // name: 'Sharp Objects', * // inStock: '£47.82', * // imgUrl: 'media/cache/32/51/3251cf3a3412f53f339e42cac2134093.jpg' * // }, * // ... * // ] * * ``` */ export declare function extractArrayFromPageUsingSelectors< T extends ListStaticExtractor >( page: Page, listExtractor: T ): Promise>;