UNPKG

@playword/core

Version:
1,109 lines (1,034 loc) 36.5 kB
import { AnthropicInput } from '@langchain/anthropic'; import { EmbeddingsParams } from '@langchain/core/embeddings'; import { GoogleGenerativeAIChatInput } from '@langchain/google-genai'; import { ChatOpenAIFields, ClientOptions } from '@langchain/openai'; import { BrowserContext, Frame, Page } from 'playwright-core'; import * as _langchain_core_messages from '@langchain/core/messages'; import { HumanMessage, AIMessage, ToolMessage } from '@langchain/core/messages'; import * as _langchain_core_documents from '@langchain/core/documents'; import { Document } from '@langchain/core/documents'; import { DynamicStructuredTool } from '@langchain/core/tools'; /** * Services for handling PlayWord's AI functionalities. * * @param opts The options for AI configuration. */ declare class AI { /** The chat model to use for the general tasks. */ private llm; /** The vector store to store the embedded documents. */ private store; constructor(opts?: AIOptions); /** * Analyze an image and extract relevant information based on user input. * * @param image The base64-encoded image to analyze. * @param input The user input to guide the analysis. */ analyzeImage(image: string, input: string): Promise<string>; /** * Classify the user's input into specific action types for agent invocation. * * @param message The user's input message. */ classifyAction(message: HumanMessage): Promise<"query" | "assertion" | "operation">; /** * Embed texts into a new vector store. * * @param texts The texts to embed. */ embedTexts(texts: string[]): Promise<void>; /** * Get the best candidate from the candidate documents. * * @param input The user's input to find the best candidate. * @param docs The candidate documents. */ getBestCandidate(input: string, docs: Document[]): Promise<number>; /** * Get the most similar documents from the vector store. * * @param query The query to search for the most similar documents. * @param topN The number of top results to return. Defaults to 10. */ searchDocuments(query: string, topN?: number): Promise<_langchain_core_documents.DocumentInterface<Record<string, any>>[]>; /** * Summarize the Observer action * * @param action The action to summarize. */ summarizeAction(action: string): Promise<string>; /** * Use custom tools to perform actions. * * @param tools The custom tools to use. * @param messages The messages to send to the AI. */ useTools(tools: DynamicStructuredTool[], messages: (AIMessage | HumanMessage | ToolMessage)[]): Promise<_langchain_core_messages.AIMessageChunk>; } /** * Assert that an element on the page or within the current frame contains a specific text. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertElementContains: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Assert that an element on the page or within the current frame does not contain a specific text. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertElementNotContain: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Assert that the content of an element on the page or within the current frame is equal to a specific text. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertElementContentEquals: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Assert that the content of an element on the page or within the current frame is not equal to a specific text. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertElementContentNotEqual: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Assert that an element on the page or within the current frame is visible. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertElementVisible: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Assert that an element on the page or within the current frame is not visible. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertElementNotVisible: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Assert that the page contains a specific text. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertPageContains: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Assert that the page does not contain a specific text. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertPageNotContain: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Assert that the page title is equal to a specific text. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertPageTitleEquals: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Assert that the page URL matches a specific regular expression. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const assertPageUrlMatches: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<boolean>; /** * Click on an element on the page or within the current frame. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const click: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<"Performed the click action" | "Failed to perform the action">; /** * Get the text content on the page based on the provided screenshot. * * @param ref The PlayWord instance. */ declare const getText: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<string>; /** * Go to a specific URL. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const goto: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<string>; /** * Hover over an element on the page or within the current frame. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const hover: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<"Failed to perform the action" | "Performed the hover action">; /** * Fill in an element on the page or within the current frame. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const input: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<"Failed to perform the action" | "Performed the input action">; /** * Press specific keys on the keyboard. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const pressKeys: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<string>; /** * Scroll the page or current frame in a specific direction. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const scroll: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<string>; /** * Select an option from a dropdown element on the page or within the current frame. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const select: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<"Failed to perform the action" | "Performed the select action">; /** * Sleep for a specific duration. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const sleep: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<string>; /** * Switch to a specific frame on the page. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const switchFrame: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<"Failed to perform the action" | "Switched to frame">; /** * Switch to a specific page on the browser. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const switchPage: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<"Failed to perform the action" | "Switched to page">; /** * Wait for a specific text to appear on the page or within the current frame. * * If the text is not found within 30 seconds, the action will fail. * * @param ref The PlayWord instance. * @param params The parameters for the action. */ declare const waitForText: (ref: PlayWordInterface, params: Partial<ActionParams>) => Promise<string>; declare const actions_assertElementContains: typeof assertElementContains; declare const actions_assertElementContentEquals: typeof assertElementContentEquals; declare const actions_assertElementContentNotEqual: typeof assertElementContentNotEqual; declare const actions_assertElementNotContain: typeof assertElementNotContain; declare const actions_assertElementNotVisible: typeof assertElementNotVisible; declare const actions_assertElementVisible: typeof assertElementVisible; declare const actions_assertPageContains: typeof assertPageContains; declare const actions_assertPageNotContain: typeof assertPageNotContain; declare const actions_assertPageTitleEquals: typeof assertPageTitleEquals; declare const actions_assertPageUrlMatches: typeof assertPageUrlMatches; declare const actions_click: typeof click; declare const actions_getText: typeof getText; declare const actions_goto: typeof goto; declare const actions_hover: typeof hover; declare const actions_input: typeof input; declare const actions_pressKeys: typeof pressKeys; declare const actions_scroll: typeof scroll; declare const actions_select: typeof select; declare const actions_sleep: typeof sleep; declare const actions_switchFrame: typeof switchFrame; declare const actions_switchPage: typeof switchPage; declare const actions_waitForText: typeof waitForText; declare namespace actions { export { actions_assertElementContains as assertElementContains, actions_assertElementContentEquals as assertElementContentEquals, actions_assertElementContentNotEqual as assertElementContentNotEqual, actions_assertElementNotContain as assertElementNotContain, actions_assertElementNotVisible as assertElementNotVisible, actions_assertElementVisible as assertElementVisible, actions_assertPageContains as assertPageContains, actions_assertPageNotContain as assertPageNotContain, actions_assertPageTitleEquals as assertPageTitleEquals, actions_assertPageUrlMatches as assertPageUrlMatches, actions_click as click, actions_getText as getText, actions_goto as goto, actions_hover as hover, actions_input as input, actions_pressKeys as pressKeys, actions_scroll as scroll, actions_select as select, actions_sleep as sleep, actions_switchFrame as switchFrame, actions_switchPage as switchPage, actions_waitForText as waitForText }; } /** * The Recorder class manages the recordings created during interactions with * PlayWord and PlayWord Observer. It provides functionality to store, retrieve, * and manipulate recordings, allowing users to save test cases for replay or review. */ declare class Recorder { private recordPath; /** * The current position in the list of recordings. * * This indicates the index of the recording currently being operated on. */ private position; /** * The list of recordings being managed. * * Each recording contains a set of actions and metadata. See {@link Recording} for the structure. */ private recordings; constructor(recordPath?: string); /** * Checks if the recording file exists and verifies that it is a JSON file. * * @param path The path to the recording file. */ private check; /** * Recursively removes a specified property from the recordings. * * @param recordings The target recordings. * @param prop The property to remove. */ private removeProperty; /** * Appends an action to the current recording. * * @param action The action to append. */ addAction(action: Action): void; /** Clears all recordings and resets the position. */ clear(): void; /** Retrieves the count of recordings. */ count(): number; /** * Deletes the recording at the specified position. * * If the position is out of bounds, this method does nothing. * * @param position The position in the recordings list to delete. */ delete(position: number): void; /** * Initializes a new recording step at the specified position. * * @param position The position in the recordings list to initialize. * @param input The input of the recording step. */ initStep(position: number, input: string): void; /** Lists all recordings. */ list(): Recording[]; /** Loads recordings from the file path. */ load(): Promise<void>; /** * Saves the current recordings to the file path. * * @param excluded The properties to exclude from the recordings before saving. */ save(excluded?: string[]): Promise<void>; } declare global { /** The custom window object to interact with the browser page. */ interface Window { /** * When assigning named functions in **page.evaluate** and run the programe with `tsx`, * an error `ReferenceError: __name is not defined` will be thrown. * * **Workaround** * * Define `__name` property in the window object to avoid the error. * * **Reference** * * https://stackoverflow.com/questions/78218772 */ __name: (fn: unknown) => unknown /** Accepts the current action and saves it to the recorder. */ accept: () => void /** Cancels the current action. */ cancel: () => void /** Clears all recorded actions in the recorder. */ clearAll: () => void /** Deletes the specified step on the timeline. */ deleteStep: (index: number) => void /** Starts the dry run process. */ dryRun: () => void /** Emits an action to the observer for processing. */ emit: (action: ObserverAction) => void /** Stop the dry run process. */ stopDryRun: () => void /** Updates the step description recorded in the observer. */ updateInput: (input: string) => void } } /** * Represents an executable action within the application. * * This interface defines the structure for actions that can be performed * using the functions provided in the `actions` module. Each action includes a * name, parameters, and an optional status indicating the success of its last execution. */ interface Action { /** * The action name to be executed. * * This must correspond to one of the functions defined in the actions module. */ name: keyof typeof actions /** Parameters to pass to the action during execution. */ params: Partial<ActionParams> /** * Indicates whether the action succeeded during the most recent execution. * * This field is optional and defaults to `undefined` if the action has not been executed. */ success?: boolean } /** * Parameters for the actions. * * This interface defines the inputs required to perform various actions * within the application. Each property corresponds to a specific type of interaction * or behavior. */ interface ActionParams { /** * Specifies the direction to scroll the page. * * Possible values: * - `up`: Scrolls the page upwards by the height of the window (`window.innerHeight`). * - `down`: Scrolls the page downwards by the height of the window (`window.innerHeight`). * - `top`: Scrolls the page to the topmost position. * - `bottom`: Scrolls the page to the bottommost position. */ direction: 'up' | 'down' | 'top' | 'bottom' /** Specifies the duration to wait before performing the action, in milliseconds. */ duration: number /** * The frame number to switch to, used for interacting with specific frames on a page. * * Frames are typically indexed starting from 0. */ frameNumber: number /** The source of the frame in which to perform the action. */ frameSrc: string /** The user input to describe how to extract the information from the page with AI. */ input: string /** * The keys to press during the action. * * This should be a string representation of the keys, such as `"Enter"`, `"Ctrl+C"`, or `"ArrowUp"`. */ keys: string /** The option to select from a dropdown menu. */ option: string /** * The page number to switch to, used when multiple pages are managed simultaneously. * * Pages are typically indexed starting from 0. */ pageNumber: number /** * A regular expression pattern to verify if the current URL matches a specific format. * * @example `^https://example.com/.*$` */ pattern: string /** The text to input into an element. */ text: string /** * The URL to navigate to. * * This should be a valid and complete URL, including the protocol (e.g., `https://`). */ url: string /** The XPath location of the element to interact with. */ xpath: string } /** * Location information for an element on the page. * * This interface provides the necessary properties to identify and describe an element for interaction on the page. */ interface ElementLocation { /** * The source URL or identifier of the frame containing the element. * * This is an optional field used when the element resides inside an iframe or frame. */ frameSrc?: string /** The full HTML content of the element, including tags, attributes, and text. */ html: string /** The XPath location of the element to interact with. */ xpath: string } /** Configuration options for the Observer class. */ interface ObserverOptions { /** * The delay in milliseconds to wait before executing each action during a dry run. * * This introduces a pause between consecutive actions to wait for loading and rendering. * * @default 250 */ delay?: number /** * The file path where the recordings will be saved. * * This specifies the location for storing recorded actions. The path should end with `.json`. * * Example: `/path/to/custom/recordings.json` * * @default '.playword/recordings.json' */ recordPath?: string } /** Configuration options for the PlayWord class. */ interface PlayWordOptions { /** * Configuration options for the AI instance. * * These options allow customization of the API client, such as specifying * an API key or custom endpoint. * * @example * **Initialize with Google and change the default model** * ```ts * const playword = new PlayWord(context, { * aiOptions: { * googleApiKey: '<your-google-api-key>', * model: 'gemini-2.0-flash' * } * }) * ``` * * **Initialize with Anthropic and VoyageAI** * ```ts * const playword = new PlayWord(context, { * aiOptions: { * anthropicApiKey: 'sk-...', * voyageAIApiKey: 'pa-...' * } * }) * ``` * * **Use a custom OpenAI endpoint** * ```ts * const playword = new PlayWord(context, { * aiOptions: { * baseURL: 'https://api.my-openai-clone.com/v1', * openAIApiKey: '<your-api-key>' * } * }) * ``` * * @default {} */ aiOptions?: AIOptions /** * Whether to enable debug mode. * * @default false */ debug?: boolean /** * The delay in milliseconds to wait before executing each action during the playback. * * This introduces a pause between actions to wait for loading and rendering. * * @default 250 */ delay?: number /** * Whether to record actions performed and where to save the recordings. * * - `true`: Records actions and saves them to `.playword/recordings.json` by default. * - `string`: Specifies a custom file path for saving the recordings. The path must end with `.json`. * - `false`: Disables action recording. * * @example * **Record actions and save to the default path** * ```ts * const playword = new PlayWord(context, { record: true }) * ``` * * **Save recordings to a custom path** * ```ts * const playword = new PlayWord(context, { * record: 'path/to/recordings.json' * }) * ``` * * **Disable recordings** * ```ts * const playword = new PlayWord(context, { record: false }) * ``` * * @default false */ record?: boolean | string } /** * Interface for interacting with PlayWord, providing functions to control the browser, * perform actions, and interact with the OpenAI API using natural language. */ interface PlayWordInterface { /** AI instance to interact with the OpenAI API. */ ai: AI /** Playwright `Context` instance used to control the browser. */ context: BrowserContext /** * The delay in milliseconds to wait before executing each action during the playback. * * This introduces a pause between actions to wait for loading and rendering. * * @default 250 */ delay: number /** * The frame within the page, if the current context is inside a frame. * * This property represents the current frame being operated on within the page. It * allows for frame-specific actions when the context is nested inside an iframe. * * - **PlayWord Observer**: The current frame will be recorded and saved to the record file. * - **PlayWord**: You can switch frames dynamically using the `say` method. * * If no frame is set, the value will be `undefined`. * * @example * **Switch to the specified frame** * ```ts * // Switch to the frame with the name "frame-name" * await playword.say('Switch to the frame "frame-name"') * // Switch to the frame with the source "https://www.example.com" * await playword.say('Switch to the frame "https://www.example.com"') * ``` */ frame?: Frame /** * The most recent input from the user. * * This stores the last natural language command provided to the `say` method. */ input: string /** * The Playwright `Page` instance used to perform actions. * * This property represents the current page being operated on. When a new page is * opened, the context will automatically switch to the new page. Additionally, * manual page switching can be performed using the `say` method. * * @example * **Switch to the specified page** * ```ts * // Switch to the first page * await playword.say('Switch to the first page') * // Switch to the second page * await playword.say('Switch to the second page') * ``` */ page?: Page /** * The recorder instance used to save the actions performed. * * If recording is not enabled or initialized, the value will be `undefined`. */ recorder?: Recorder /** * Step count to keep track of the actions performed. * This is used to locate the recording in the record file. */ stepCount: number /** * Executes actions on the page using natural language input. * * Converts the provided input into corresponding actions and performs them * on the browser page. * * @param message Natural language input to specify the action. * * @example * **Navigate to a webpage** * ```ts * const playword = new PlayWord(context) * await playword.say('Go to https://www.google.com') * ``` * * **Click a link** * ```ts * await playword.say('Click the "Gmail" link') * ``` * * **Check for page content** * ```ts * const result = await playword.say('Does the page contain "Sign in"?') * // Output: true * ``` */ say(message: string): Promise<ActionResult> } /** * Represents a recording of actions performed during user interactions. * * This interface includes the input message and the actions performed in one step. */ interface Recording { /** Input message to map actions performed. */ input: string /** Actions performed in one step. */ actions: Action[] } /** * Represents the current state of the observer. * * The `ObserverState` interface tracks various states during the execution of the observer. */ interface ObserverState { /** Indicates whether the observer is currently performing a dry run. */ dryRunning?: boolean /** * Indicates whether the Observer is waiting for AI to generate * a step description or adjust the current action. */ waitingForAI?: boolean /** * Indicates whether the Observer is waiting for user input * to accept, modify, or drop the action. */ waitingForUserAction?: boolean } /** * Interface that extends EmbeddingsParams and defines additional * parameters specific to the VoyageEmbeddings class. */ interface VoyageEmbeddingsParams extends EmbeddingsParams { /** The VoyageAI API key. */ apiKey?: string /** * The maximum number of documents to embed in a single request. * * This is limited by the VoyageAI API to a maximum of 8. * * @default 8 */ batchSize?: number /** * The endpoint URL for the VoyageAI API. * * @default 'https://api.voyageai.com/v1/embeddings' */ endpoint?: string /** * Input type for the embeddings request. Can be "query", or "document". * * @default undefined */ inputType?: 'query' | 'document' /** * The embeddings model to use. * * @default 'voyage-3' */ model?: string /** * The desired dimension of the output embeddings. * * @default undefined */ outputDimension?: number /** * The data type of the output embeddings. Can be "float" or "int8". * * @default 'float' */ outputDtype?: 'float' | 'int8' /** * Whether to truncate the input texts to the maximum length allowed by the model. * * @default true */ truncation?: boolean } /** * The response from an action performed on the page. * * - For assertion actions, the result is a boolean value indicating success (`true`) or failure (`false`). * - For non-assertion actions, the result is a string message describing the outcome. * - For multiple actions, the result is an array of strings or booleans. */ type ActionResult = boolean | string /** Configuration for the AI class. */ type AIOptions = GoogleOptions | OpenAIOptions | AnthropicOptions | VoyageOptions /** Anthropic configuration options. */ type AnthropicOptions = Partial<AnthropicInput> & ClientOptions /** Google configuration options. */ type GoogleOptions = Partial<GoogleGenerativeAIChatInput> & { /** The API key for the Google API. */ googleApiKey?: string } /** OpenAI configuration options. */ type OpenAIOptions = Partial<ChatOpenAIFields> & ClientOptions /** VoyageAI configuration options. */ type VoyageOptions = Partial<VoyageEmbeddingsParams> & { /** The VoyageAI API key. */ voyageAIApiKey?: string } /** * Represents an action observed during user interactions. * * This type includes various action types and their associated parameters. */ type ObserverAction = | { /** The name of the action. */ name: 'click' /** * The parameters for the `click` action. * * Includes the location of the element to be clicked. */ params: ElementLocation } | { /** The name of the action. */ name: 'hover' /** * The parameters for the `hover` action. * * Includes the location of the element and the duration of the hover action. */ params: ElementLocation & { duration: number } } | { /** The name of the action. */ name: 'input' /** * The parameters for the `input` action. * * Includes the location of the element and the text to input. */ params: ElementLocation & { text: string } } | { /** The name of the action. */ name: 'select' /** * The parameters for the `select` action. * * Includes the location of the dropdown element and the option to select. */ params: ElementLocation & { option: string } } | { /** The name of the action. */ name: 'goto' /** * The parameters for the `goto` action. * * Includes the URL to navigate to. */ params: { url: string } } /** * PlayWord Observer enables tracking and recording user interactions on a webpage. * * By leveraging AI, the Observer converts user behaviors into precise and reliable * test cases, making it an essential tool for automated testing of web applications. * * **Features:** * - Observes user interactions and translates them into executable test cases. * - Mounts a user interface on all opened pages using Playwright's `addInitScript` method, * allowing seamless interaction with the Observer. * - Integrates with PlayWord for executing the recorded test cases. * * **Usage:** * This class works in conjunction with the PlayWord framework. The recorded test cases * can be directly executed via the provided PlayWord instance. * * @param playword The PlayWord instance used to control the browser and leverage AI. * @param observerOptions Optional configuration for the Observer. See {@link ObserverOptions} for details. * * @example * **Initialize and Use the Observer** * ```ts * // Initialize a PlayWord instance * const playword = new PlayWord(context) * * // Create an Observer instance and start observing * const observer = new Observer(playword, { delay: 500 }) * await observer.observe() * ``` */ declare class Observer { private playword; /** * Represents the current page action being performed. * See {@link Action} for details. */ private action; /** * The delay in milliseconds to wait before executing each action during a dry run. * * This introduces a pause between consecutive actions, allowing time for * the page to load and render properly. * * @default 250 */ private delay; /** The step description for the current action. */ private input; /** The recorder instance used to save the actions performed. */ private recorder; /** * The current state of the Observer. * See {@link ObserverState} for details. */ state: ObserverState; constructor(playword: PlayWordInterface, { delay, recordPath }?: ObserverOptions); /** Retrieves the AI instance from the PlayWord instance. */ private ai; /** Retrieves the current context from the PlayWord instance. */ private context; /** Retrieves the current page from the PlayWord instance. */ private page; /** Set up the Observer scripts and listeners on the page. */ private setPageListeners; /** Starts observing the user interactions on the page. */ observe(): Promise<void>; } /** * PlayWord enables users to automate browsers with AI. * * This class simplifies browser automation by removing the need to locate elements * manually using selectors. Instead, you can describe your desired actions in natural * language, and PlayWord will interpret and execute them. * * **Repository**: [GitHub - PlayWord](https://github.com/Foreverskyin0216/playword) * * @param context The Playwright `Context` instance used to control the browser. * @param playwordOptions Optional configuration for PlayWord. See {@link PlayWordOptions} for details. * * @example * **Create a new PlayWord instance** * ```ts * const context = await browser.newContext() * const playword = new PlayWord(context, { * aiOptions: { * openAIApiKey: '<your-api-key>' * }, * debug: true, * delay: 500, * record: 'spec/test-login.json' * }) * ``` */ declare class PlayWord implements PlayWordInterface { context: BrowserContext; /** AI instance to interact with the OpenAI API. */ ai: AI; /** * The delay in milliseconds to wait before executing each action during the playback. * * This introduces a pause between actions to wait for loading and rendering. * * @default 250 */ delay: number; /** * The frame within the page, if the current context is inside a frame. * * This property represents the current frame being operated on within the page. It * allows for frame-specific actions when the context is nested inside an iframe. * * - **PlayWord Observer**: The current frame will be recorded and saved to the record file. * - **PlayWord**: You can switch frames dynamically using the `say` method. * * If no frame is set, the value will be `undefined`. * * @example * **Switch to the specified frame** * ```ts * // Switch to the frame with the name "frame-name" * await playword.say('Switch to the frame "frame-name"') * // Switch to the frame with the source "https://www.example.com" * await playword.say('Switch to the frame "https://www.example.com"') * ``` */ frame?: Frame; /** * The most recent input from the user. * * This stores the last natural language command provided to the `say` method. */ input: string; /** * The Playwright `Page` instance used to perform actions. * * This property represents the current page being operated on. When a new page is * opened, the context will automatically switch to the new page. Additionally, * manual page switching can be performed using the `say` method. * * @example * **Switch to the specified page** * ```ts * // Switch to the first page * await playword.say('Switch to the first page') * // Switch to the second page * await playword.say('Switch to the second page') * ``` */ page?: Page; /** * The recorder instance used to save the actions performed. * * If recording is not enabled or initialized, the value will be `undefined`. */ recorder?: Recorder; /** * Step count to keep track of the actions performed. * This is used to locate the recording in the record file. */ stepCount: number; /** * Cache for storing retrieved data during tool calls. */ cache: ActionResult[]; constructor(context: BrowserContext, { debug, delay, aiOptions, record }?: PlayWordOptions); /** * The decorator to handle the test fixture, including the setup process and teardown process. * * **Setup:** * - If the page is not initialized, create a new page. * - If recording is enabled, load the recordings from the record file. * - If the input starts with the AI pattern, replace the AI pattern with an empty string for the input. * * **Teardown:** * - Increment the step count to locate the recording in the record file. */ private static fixture; /** Invoke the PlayWord graph to perform actions. */ private usePlayWordGraph; /** * Use recordings to perform actions. If the action fails, retry with AI. * * @param recording The recording to perform actions. See {@link Recording} for details. */ private useRecording; /** * Executes actions on the page using natural language input. * * Converts the provided input into corresponding actions and performs them * on the browser page. * * @param message Natural language input to specify the action. * * @example * **Navigate to a webpage** * ```ts * const playword = new PlayWord(context) * await playword.say('Navigate to https://www.google.com') * ``` * * **Click a link** * ```ts * await playword.say('Click the "Gmail" link') * ``` * * **Check for page content** * ```ts * const result = await playword.say('Check if the page contains "Sign in"') * // Output: true * ``` */ say(message: string): Promise<ActionResult>; } export { Observer, PlayWord };