@stablyai/playwright-base 2.0.12-rc.1 → 2.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +102 -151
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +227 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.d.mts.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +71 -111
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import * as _playwright_test from '@playwright/test';
|
|
2
|
+
import { BrowserContext, Page, Locator, MatcherReturnType, Browser, BrowserType } from '@playwright/test';
|
|
3
|
+
import * as z4 from 'zod/v4/core';
|
|
4
|
+
|
|
5
|
+
type AnthropicModel = "anthropic/claude-sonnet-4-5-20250929";
|
|
6
|
+
type GeminiModel = "google/gemini-2.5-computer-use-preview-10-2025";
|
|
7
|
+
type Model = AnthropicModel | GeminiModel | (string & {});
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Options for configuring agent behavior during execution.
|
|
11
|
+
*/
|
|
12
|
+
type AgentActOptions = {
|
|
13
|
+
/**
|
|
14
|
+
* The page the agent will operate on.
|
|
15
|
+
*/
|
|
16
|
+
page: Page;
|
|
17
|
+
/**
|
|
18
|
+
* Maximum number of thinking cycles the agent can perform.
|
|
19
|
+
* Each cycle includes observing the page, planning, and executing one or more actions.
|
|
20
|
+
* @default 30
|
|
21
|
+
*/
|
|
22
|
+
maxCycles?: number;
|
|
23
|
+
/**
|
|
24
|
+
* AI model to use for agent reasoning.
|
|
25
|
+
* Different models may have different capabilities and performance characteristics.
|
|
26
|
+
*/
|
|
27
|
+
model?: Model;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* AI agent for automating browser interactions using natural language.
|
|
31
|
+
*
|
|
32
|
+
* The Agent can perform complex browser actions by interpreting natural language instructions.
|
|
33
|
+
* It observes the page state, makes decisions, and executes actions autonomously.
|
|
34
|
+
*
|
|
35
|
+
* Agents are created via {@link BrowserContext.newAgent} or {@link Browser.newAgent}.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const agent = context.newAgent();
|
|
40
|
+
* await agent.act('Fill out the login form and submit', { page });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare class Agent {
|
|
44
|
+
readonly browserContext: BrowserContext;
|
|
45
|
+
constructor(browserContext: BrowserContext);
|
|
46
|
+
/**
|
|
47
|
+
* Instructs the agent to perform actions on the page using natural language.
|
|
48
|
+
*
|
|
49
|
+
* The agent will analyze the page, plan actions, and execute them autonomously.
|
|
50
|
+
* It can perform multiple actions such as clicking, typing, navigating, and verifying
|
|
51
|
+
* page state based on the provided instruction.
|
|
52
|
+
*
|
|
53
|
+
* @param prompt - Natural language instruction describing what the agent should do
|
|
54
|
+
* @param options - Configuration for the agent's behavior including the page to operate on
|
|
55
|
+
* @returns Promise that resolves when the agent successfully completes the task
|
|
56
|
+
* @throws {Error} Throws an error if the agent fails to complete the task. The error message includes the AI's reasoning for the failure.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* // Simple action
|
|
61
|
+
* await agent.act('Click the login button', { page });
|
|
62
|
+
*
|
|
63
|
+
* // Complex multi-step action
|
|
64
|
+
* await agent.act('Navigate to settings, enable notifications, and save changes', { page });
|
|
65
|
+
*
|
|
66
|
+
* // With custom options
|
|
67
|
+
* await agent.act('Complete the checkout process', {
|
|
68
|
+
* page,
|
|
69
|
+
* maxCycles: 20,
|
|
70
|
+
* model: 'gpt-4'
|
|
71
|
+
* });
|
|
72
|
+
*
|
|
73
|
+
* // Handling failures with try-catch
|
|
74
|
+
* try {
|
|
75
|
+
* await agent.act('Complete the task', { page });
|
|
76
|
+
* console.log('Agent completed the task successfully');
|
|
77
|
+
* } catch (error) {
|
|
78
|
+
* console.error('Agent failed:', error.message);
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
act(prompt: string, options: AgentActOptions): Promise<void>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type ExtractSchema = {
|
|
86
|
+
safeParseAsync(data: unknown, params?: z4.ParseContext<z4.$ZodIssue>): Promise<z4.util.SafeParseResult<z4.output<any>>>;
|
|
87
|
+
} & z4.$ZodType;
|
|
88
|
+
type SchemaOutput<T extends ExtractSchema> = z4.output<T>;
|
|
89
|
+
|
|
90
|
+
type MatcherContext = {
|
|
91
|
+
isNot: boolean;
|
|
92
|
+
message?: () => string;
|
|
93
|
+
};
|
|
94
|
+
declare const stablyPlaywrightMatchers: {
|
|
95
|
+
readonly toMatchScreenshotPrompt: (this: MatcherContext, received: Page | Locator, condition: string, options?: ScreenshotPromptOptions) => Promise<MatcherReturnType>;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
declare function augmentLocator<T extends Locator>(locator: T): T;
|
|
99
|
+
declare function augmentPage<T extends Page>(page: T): T;
|
|
100
|
+
declare function augmentBrowserContext<T extends BrowserContext>(context: T): T;
|
|
101
|
+
declare function augmentBrowser<T extends Browser>(browser: T): T;
|
|
102
|
+
declare function augmentBrowserType<TBrowser extends Browser>(browserType: BrowserType<TBrowser>): BrowserType<TBrowser>;
|
|
103
|
+
|
|
104
|
+
declare function setApiKey(apiKey: string): void;
|
|
105
|
+
declare function requireApiKey(): string;
|
|
106
|
+
|
|
107
|
+
type ScreenshotPromptOptions = _playwright_test.PageAssertionsToHaveScreenshotOptions;
|
|
108
|
+
|
|
109
|
+
type Expect<T = Page> = {
|
|
110
|
+
toMatchScreenshotPrompt(condition: string, options?: ScreenshotPromptOptions): Promise<void>;
|
|
111
|
+
};
|
|
112
|
+
declare module "@playwright/test" {
|
|
113
|
+
interface Locator {
|
|
114
|
+
/**
|
|
115
|
+
* Extracts information from this locator using Stably AI.
|
|
116
|
+
*
|
|
117
|
+
* Takes a screenshot of the locator and uses AI to extract information based on the
|
|
118
|
+
* provided prompt. When a schema is provided, the extracted data is validated and
|
|
119
|
+
* typed according to the schema.
|
|
120
|
+
*
|
|
121
|
+
* @param prompt - A natural language description of what information to extract
|
|
122
|
+
* @returns A string containing the extracted information
|
|
123
|
+
*/
|
|
124
|
+
extract(prompt: string): Promise<string>;
|
|
125
|
+
/**
|
|
126
|
+
* Extracts information from this locator using Stably AI.
|
|
127
|
+
*
|
|
128
|
+
* Takes a screenshot of the locator and uses AI to extract information based on the
|
|
129
|
+
* provided prompt. The extracted data is validated and typed according to the schema.
|
|
130
|
+
*
|
|
131
|
+
* @param prompt - A natural language description of what information to extract
|
|
132
|
+
* @param options - Configuration object containing the Zod schema for validation
|
|
133
|
+
* @param options.schema - Zod schema to validate and type the extracted data
|
|
134
|
+
* @returns Typed data matching the provided schema
|
|
135
|
+
*/
|
|
136
|
+
extract<T extends ExtractSchema>(prompt: string, options: {
|
|
137
|
+
schema: T;
|
|
138
|
+
}): Promise<SchemaOutput<T>>;
|
|
139
|
+
}
|
|
140
|
+
interface Page {
|
|
141
|
+
/**
|
|
142
|
+
* Extracts information from this page using Stably AI.
|
|
143
|
+
*
|
|
144
|
+
* Takes a screenshot of the page and uses AI to extract information based on the
|
|
145
|
+
* provided prompt. When a schema is provided, the extracted data is validated and
|
|
146
|
+
* typed according to the schema.
|
|
147
|
+
*
|
|
148
|
+
* @param prompt - A natural language description of what information to extract
|
|
149
|
+
* @returns A string containing the extracted information
|
|
150
|
+
*/
|
|
151
|
+
extract(prompt: string): Promise<string>;
|
|
152
|
+
/**
|
|
153
|
+
* Extracts information from this page using Stably AI.
|
|
154
|
+
*
|
|
155
|
+
* Takes a screenshot of the page and uses AI to extract information based on the
|
|
156
|
+
* provided prompt. The extracted data is validated and typed according to the schema.
|
|
157
|
+
*
|
|
158
|
+
* @param prompt - A natural language description of what information to extract
|
|
159
|
+
* @param options - Configuration object containing the Zod schema for validation
|
|
160
|
+
* @param options.schema - Zod schema to validate and type the extracted data
|
|
161
|
+
* @returns Typed data matching the provided schema
|
|
162
|
+
*/
|
|
163
|
+
extract<T extends ExtractSchema>(prompt: string, options: {
|
|
164
|
+
schema: T;
|
|
165
|
+
}): Promise<SchemaOutput<T>>;
|
|
166
|
+
}
|
|
167
|
+
interface BrowserContext {
|
|
168
|
+
/**
|
|
169
|
+
* Creates a new AI agent instance for automating browser interactions.
|
|
170
|
+
*
|
|
171
|
+
* An agent can perform complex browser actions by interpreting natural language instructions.
|
|
172
|
+
* It observes the page, makes autonomous decisions, and executes actions like clicking,
|
|
173
|
+
* typing, navigating, and verifying page state.
|
|
174
|
+
*
|
|
175
|
+
* The agent operates within this browser context and can interact with all pages in the context.
|
|
176
|
+
* Use the returned agent's [agent.act(prompt, options)](#agent-act) method to give instructions.
|
|
177
|
+
* The page to operate on is specified when calling `act()`.
|
|
178
|
+
*
|
|
179
|
+
* **Usage**
|
|
180
|
+
*
|
|
181
|
+
* ```js
|
|
182
|
+
* const context = await browser.newContext();
|
|
183
|
+
* const page = await context.newPage();
|
|
184
|
+
* await page.goto('https://example.com');
|
|
185
|
+
*
|
|
186
|
+
* // Create an agent for this context
|
|
187
|
+
* const agent = context.newAgent();
|
|
188
|
+
*
|
|
189
|
+
* // Give the agent natural language instructions with the page to operate on
|
|
190
|
+
* await agent.act('Click the login button and enter credentials', { page });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
newAgent(): Agent;
|
|
194
|
+
}
|
|
195
|
+
interface Browser {
|
|
196
|
+
/**
|
|
197
|
+
* Creates a new AI agent instance for automating browser interactions.
|
|
198
|
+
*
|
|
199
|
+
* An agent can perform complex browser actions by interpreting natural language instructions.
|
|
200
|
+
* It observes the page, makes autonomous decisions, and executes actions like clicking,
|
|
201
|
+
* typing, navigating, and verifying page state.
|
|
202
|
+
*
|
|
203
|
+
* The agent operates within a browser context and can interact with all pages in that context.
|
|
204
|
+
* Use the returned agent's [agent.act(prompt, options)](#agent-act) method to give instructions.
|
|
205
|
+
* The page to operate on is specified when calling `act()`.
|
|
206
|
+
*
|
|
207
|
+
* **Usage**
|
|
208
|
+
*
|
|
209
|
+
* ```js
|
|
210
|
+
* const browser = await chromium.launch();
|
|
211
|
+
* const page = await browser.newPage();
|
|
212
|
+
* await page.goto('https://example.com');
|
|
213
|
+
*
|
|
214
|
+
* // Create an agent
|
|
215
|
+
* const agent = browser.newAgent();
|
|
216
|
+
*
|
|
217
|
+
* // Give the agent natural language instructions with the page to operate on
|
|
218
|
+
* await agent.act('Fill out the registration form and submit', { page });
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
newAgent(): Agent;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export { Agent, augmentBrowser, augmentBrowserContext, augmentBrowserType, augmentLocator, augmentPage, requireApiKey, setApiKey, stablyPlaywrightMatchers };
|
|
226
|
+
export type { Expect, ExtractSchema, SchemaOutput, ScreenshotPromptOptions };
|
|
227
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","sources":["../src/playwright-augment/methods/agent/models.ts","../src/playwright-augment/methods/agent.ts","../src/ai/extract.ts","../src/expect.ts","../src/playwright-augment/augment.ts","../src/runtime.ts","../src/index.ts"],"mappings":";;;;AAAA,KAAK,cAAc;AACnB,KAAK,WAAW;AACV,KAAM,KAAK,GAAG,cAAc,GAAG,WAAW;;ACchD;;;AAGA,KAAK,eAAe;;;;UAIZ,IAAI;;;;;;;;;;;YAWF,KAAK;;AAQf;;;;;;;;;;;;;;AAcA,cAAa,KAAK;6BACqB,cAAc;gCAAd,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAsChB,eAAe,GAAG,OAAO;;;ACnFxD,KAAM,aAAa;2CAGZ,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,IAEpC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM;IAC1C,EAAE,CAAC,QAAQ;AAET,KAAM,YAAY,WAAW,aAAa,IAAI,EAAE,CAAC,MAAM;;ACT7D,KAAK,cAAc;;;;AA+BnB,cAAa,wBAAwB;6CAE3B,cAAc,YACV,IAAI,GAAG,OAAO,+BAEd,uBAAuB,KAChC,OAAO,CAAC,iBAAiB;;;AChB9B,iBAAgB,cAAc,WAAW,OAAO;AAchD,iBAAgB,WAAW,WAAW,IAAI;AAiB1C,iBAAgB,qBAAqB,WAAW,cAAc;AA8B9D,iBAAgB,cAAc,WAAW,OAAO;AAuChD,iBAAgB,kBAAkB,kBAAkB,OAAO,eAC5C,WAAW,aACvB,WAAW;;ACpId,iBAAgB,SAAS;AAQzB,iBAAgB,aAAa;;ACQvB,KAAM,uBAAuB,GAEjC,gBAAyB,CAAE,qCAAqC;;AAY5D,KAAM,MAAM,KAAKA,IAAY;yDAGrB,uBAAuB,GAChC,OAAO;;AAGZ;;;;;;;;;;;;iCAa6B,OAAO;;;;;;;;;;;;0BAYd,aAAa;;YAG5B,OAAO,CAAC,YAAY;;;;;;;;;;;;;iCAeE,OAAO;;;;;;;;;;;;0BAYd,aAAa;;YAG5B,OAAO,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA+BXC,KAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA+BlDA,KAAkD","names":["InternalPage","__playwright_augment_methods_agent.Agent"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -222,4 +222,6 @@ declare module "@playwright/test" {
|
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
export { Agent,
|
|
225
|
+
export { Agent, augmentBrowser, augmentBrowserContext, augmentBrowserType, augmentLocator, augmentPage, requireApiKey, setApiKey, stablyPlaywrightMatchers };
|
|
226
|
+
export type { Expect, ExtractSchema, SchemaOutput, ScreenshotPromptOptions };
|
|
227
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sources":["../src/playwright-augment/methods/agent/models.ts","../src/playwright-augment/methods/agent.ts","../src/ai/extract.ts","../src/expect.ts","../src/playwright-augment/augment.ts","../src/runtime.ts","../src/index.ts"],"mappings":";;;;AAAA,KAAK,cAAc;AACnB,KAAK,WAAW;AACV,KAAM,KAAK,GAAG,cAAc,GAAG,WAAW;;ACchD;;;AAGA,KAAK,eAAe;;;;UAIZ,IAAI;;;;;;;;;;;YAWF,KAAK;;AAQf;;;;;;;;;;;;;;AAcA,cAAa,KAAK;6BACqB,cAAc;gCAAd,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAsChB,eAAe,GAAG,OAAO;;;ACnFxD,KAAM,aAAa;2CAGZ,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,IAEpC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM;IAC1C,EAAE,CAAC,QAAQ;AAET,KAAM,YAAY,WAAW,aAAa,IAAI,EAAE,CAAC,MAAM;;ACT7D,KAAK,cAAc;;;;AA+BnB,cAAa,wBAAwB;6CAE3B,cAAc,YACV,IAAI,GAAG,OAAO,+BAEd,uBAAuB,KAChC,OAAO,CAAC,iBAAiB;;;AChB9B,iBAAgB,cAAc,WAAW,OAAO;AAchD,iBAAgB,WAAW,WAAW,IAAI;AAiB1C,iBAAgB,qBAAqB,WAAW,cAAc;AA8B9D,iBAAgB,cAAc,WAAW,OAAO;AAuChD,iBAAgB,kBAAkB,kBAAkB,OAAO,eAC5C,WAAW,aACvB,WAAW;;ACpId,iBAAgB,SAAS;AAQzB,iBAAgB,aAAa;;ACQvB,KAAM,uBAAuB,GAEjC,gBAAyB,CAAE,qCAAqC;;AAY5D,KAAM,MAAM,KAAKA,IAAY;yDAGrB,uBAAuB,GAChC,OAAO;;AAGZ;;;;;;;;;;;;iCAa6B,OAAO;;;;;;;;;;;;0BAYd,aAAa;;YAG5B,OAAO,CAAC,YAAY;;;;;;;;;;;;;iCAeE,OAAO;;;;;;;;;;;;0BAYd,aAAa;;YAG5B,OAAO,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA+BXC,KAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA+BlDA,KAAkD","names":["InternalPage","__playwright_augment_methods_agent.Agent"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -222,4 +222,6 @@ declare module "@playwright/test" {
|
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
export { Agent,
|
|
225
|
+
export { Agent, augmentBrowser, augmentBrowserContext, augmentBrowserType, augmentLocator, augmentPage, requireApiKey, setApiKey, stablyPlaywrightMatchers };
|
|
226
|
+
export type { Expect, ExtractSchema, SchemaOutput, ScreenshotPromptOptions };
|
|
227
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":["../src/playwright-augment/methods/agent/models.ts","../src/playwright-augment/methods/agent.ts","../src/ai/extract.ts","../src/expect.ts","../src/playwright-augment/augment.ts","../src/runtime.ts","../src/index.ts"],"mappings":";;;;AAAA,KAAK,cAAc;AACnB,KAAK,WAAW;AACV,KAAM,KAAK,GAAG,cAAc,GAAG,WAAW;;ACchD;;;AAGA,KAAK,eAAe;;;;UAIZ,IAAI;;;;;;;;;;;YAWF,KAAK;;AAQf;;;;;;;;;;;;;;AAcA,cAAa,KAAK;6BACqB,cAAc;gCAAd,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAsChB,eAAe,GAAG,OAAO;;;ACnFxD,KAAM,aAAa;2CAGZ,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,IAEpC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM;IAC1C,EAAE,CAAC,QAAQ;AAET,KAAM,YAAY,WAAW,aAAa,IAAI,EAAE,CAAC,MAAM;;ACT7D,KAAK,cAAc;;;;AA+BnB,cAAa,wBAAwB;6CAE3B,cAAc,YACV,IAAI,GAAG,OAAO,+BAEd,uBAAuB,KAChC,OAAO,CAAC,iBAAiB;;;AChB9B,iBAAgB,cAAc,WAAW,OAAO;AAchD,iBAAgB,WAAW,WAAW,IAAI;AAiB1C,iBAAgB,qBAAqB,WAAW,cAAc;AA8B9D,iBAAgB,cAAc,WAAW,OAAO;AAuChD,iBAAgB,kBAAkB,kBAAkB,OAAO,eAC5C,WAAW,aACvB,WAAW;;ACpId,iBAAgB,SAAS;AAQzB,iBAAgB,aAAa;;ACQvB,KAAM,uBAAuB,GAEjC,gBAAyB,CAAE,qCAAqC;;AAY5D,KAAM,MAAM,KAAKA,IAAY;yDAGrB,uBAAuB,GAChC,OAAO;;AAGZ;;;;;;;;;;;;iCAa6B,OAAO;;;;;;;;;;;;0BAYd,aAAa;;YAG5B,OAAO,CAAC,YAAY;;;;;;;;;;;;;iCAeE,OAAO;;;;;;;;;;;;0BAYd,aAAa;;YAG5B,OAAO,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA+BXC,KAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA+BlDA,KAAkD","names":["InternalPage","__playwright_augment_methods_agent.Agent"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
-
});
|
|
1
|
+
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { test } from '@playwright/test';
|
|
2
|
+
import * as jpeg from 'jpeg-js';
|
|
3
|
+
import { PNG } from 'pngjs';
|
|
4
|
+
import pRetry from 'p-retry';
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
import { test } from "@playwright/test";
|
|
10
|
-
|
|
11
|
-
// src/runtime.ts
|
|
12
|
-
var configuredApiKey = process.env.STABLY_API_KEY;
|
|
6
|
+
let configuredApiKey = process.env.STABLY_API_KEY;
|
|
13
7
|
function setApiKey(apiKey) {
|
|
14
8
|
configuredApiKey = apiKey;
|
|
15
9
|
}
|
|
@@ -26,25 +20,22 @@ function requireApiKey() {
|
|
|
26
20
|
return apiKey;
|
|
27
21
|
}
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
var isObject = (value) => {
|
|
23
|
+
const isObject = (value) => {
|
|
31
24
|
return typeof value === "object" && value !== null;
|
|
32
25
|
};
|
|
33
26
|
|
|
34
|
-
|
|
35
|
-
var SDK_METADATA_HEADERS = {
|
|
27
|
+
const SDK_METADATA_HEADERS = {
|
|
36
28
|
"X-Client-Name": "stably-playwright-sdk-js",
|
|
37
|
-
"X-Client-Version": "2.0.12
|
|
29
|
+
"X-Client-Version": "2.0.12"
|
|
38
30
|
};
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
var PROMPT_ASSERTION_ENDPOINT = new URL(
|
|
32
|
+
const PROMPT_ASSERTION_PATH = "internal/v2/assert";
|
|
33
|
+
const STABLY_API_URL$2 = process.env.STABLY_API_URL || "https://api.stably.ai";
|
|
34
|
+
const PROMPT_ASSERTION_ENDPOINT = new URL(
|
|
44
35
|
PROMPT_ASSERTION_PATH,
|
|
45
|
-
STABLY_API_URL
|
|
36
|
+
STABLY_API_URL$2
|
|
46
37
|
).toString();
|
|
47
|
-
|
|
38
|
+
const parseSuccessResponse = (value) => {
|
|
48
39
|
if (!isObject(value)) {
|
|
49
40
|
throw new Error("Verify prompt returned unexpected response shape");
|
|
50
41
|
}
|
|
@@ -60,7 +51,7 @@ var parseSuccessResponse = (value) => {
|
|
|
60
51
|
success
|
|
61
52
|
};
|
|
62
53
|
};
|
|
63
|
-
|
|
54
|
+
const parseErrorResponse = (value) => {
|
|
64
55
|
if (!isObject(value)) {
|
|
65
56
|
return void 0;
|
|
66
57
|
}
|
|
@@ -105,7 +96,6 @@ async function verifyPrompt({
|
|
|
105
96
|
);
|
|
106
97
|
}
|
|
107
98
|
|
|
108
|
-
// src/playwright-type-predicates.ts
|
|
109
99
|
function isPage(candidate) {
|
|
110
100
|
return typeof candidate === "object" && candidate !== null && typeof candidate.screenshot === "function" && typeof candidate.goto === "function";
|
|
111
101
|
}
|
|
@@ -113,10 +103,6 @@ function isLocator(candidate) {
|
|
|
113
103
|
return typeof candidate === "object" && candidate !== null && typeof candidate.screenshot === "function" && typeof candidate.nth === "function";
|
|
114
104
|
}
|
|
115
105
|
|
|
116
|
-
// src/image-compare.ts
|
|
117
|
-
import * as jpeg from "jpeg-js";
|
|
118
|
-
|
|
119
|
-
// ../../node_modules/.pnpm/pixelmatch@7.1.0/node_modules/pixelmatch/index.js
|
|
120
106
|
function pixelmatch(img1, img2, output, width, height, options = {}) {
|
|
121
107
|
const {
|
|
122
108
|
threshold = 0.1,
|
|
@@ -272,15 +258,13 @@ function drawGrayPixel(img, i, alpha, output) {
|
|
|
272
258
|
drawPixel(output, i, val, val, val);
|
|
273
259
|
}
|
|
274
260
|
|
|
275
|
-
|
|
276
|
-
import { PNG } from "pngjs";
|
|
277
|
-
var isPng = (buffer) => {
|
|
261
|
+
const isPng = (buffer) => {
|
|
278
262
|
return buffer.length >= 8 && buffer[0] === 137 && buffer[1] === 80 && buffer[2] === 78 && buffer[3] === 71 && buffer[4] === 13 && buffer[5] === 10 && buffer[6] === 26 && buffer[7] === 10;
|
|
279
263
|
};
|
|
280
|
-
|
|
264
|
+
const isJpeg = (buffer) => {
|
|
281
265
|
return buffer.length >= 2 && buffer[0] === 255 && buffer[1] === 216;
|
|
282
266
|
};
|
|
283
|
-
|
|
267
|
+
const decodeImage = (buffer) => {
|
|
284
268
|
if (isPng(buffer)) {
|
|
285
269
|
const png2 = PNG.sync.read(buffer);
|
|
286
270
|
return { data: png2.data, height: png2.height, width: png2.width };
|
|
@@ -292,7 +276,7 @@ var decodeImage = (buffer) => {
|
|
|
292
276
|
const png = PNG.sync.read(buffer);
|
|
293
277
|
return { data: png.data, height: png.height, width: png.width };
|
|
294
278
|
};
|
|
295
|
-
|
|
279
|
+
const imagesAreSimilar = ({
|
|
296
280
|
image1,
|
|
297
281
|
image2,
|
|
298
282
|
threshold
|
|
@@ -316,7 +300,6 @@ var imagesAreSimilar = ({
|
|
|
316
300
|
return numDiffPixels === 0;
|
|
317
301
|
};
|
|
318
302
|
|
|
319
|
-
// src/screenshot.ts
|
|
320
303
|
async function takeStableScreenshot(target, options) {
|
|
321
304
|
const page = isPage(target) ? target : target.page();
|
|
322
305
|
const totalTimeout = options?.timeout ?? 5e3;
|
|
@@ -363,8 +346,7 @@ async function takeStableScreenshot(target, options) {
|
|
|
363
346
|
return actual ?? await safeScreenshot();
|
|
364
347
|
}
|
|
365
348
|
|
|
366
|
-
|
|
367
|
-
var MAX_ATTACHMENT_NAME_LENGTH = 80;
|
|
349
|
+
const MAX_ATTACHMENT_NAME_LENGTH = 80;
|
|
368
350
|
function createFailureMessage({
|
|
369
351
|
condition,
|
|
370
352
|
didPass,
|
|
@@ -382,7 +364,7 @@ Reason: ${reason}`;
|
|
|
382
364
|
}
|
|
383
365
|
return message;
|
|
384
366
|
}
|
|
385
|
-
|
|
367
|
+
const stablyPlaywrightMatchers = {
|
|
386
368
|
async toMatchScreenshotPrompt(received, condition, options) {
|
|
387
369
|
const target = isPage(received) ? received : isLocator(received) ? received : void 0;
|
|
388
370
|
if (!target) {
|
|
@@ -438,14 +420,8 @@ var stablyPlaywrightMatchers = {
|
|
|
438
420
|
}
|
|
439
421
|
};
|
|
440
422
|
|
|
441
|
-
|
|
442
|
-
import { test as test2 } from "@playwright/test";
|
|
443
|
-
import pRetry from "p-retry";
|
|
423
|
+
const truncate = (inp, length) => inp.length <= length || inp.length <= 3 ? inp : `${inp.slice(0, length - 3)}...`;
|
|
444
424
|
|
|
445
|
-
// src/utils/truncate.ts
|
|
446
|
-
var truncate = (inp, length) => inp.length <= length || inp.length <= 3 ? inp : `${inp.slice(0, length - 3)}...`;
|
|
447
|
-
|
|
448
|
-
// src/playwright-augment/methods/agent/construct-payload.ts
|
|
449
425
|
function constructAgentPayload({
|
|
450
426
|
activePage,
|
|
451
427
|
additionalContext,
|
|
@@ -493,7 +469,6 @@ function constructAgentPayload({
|
|
|
493
469
|
return form;
|
|
494
470
|
}
|
|
495
471
|
|
|
496
|
-
// src/playwright-augment/methods/agent/scroll-helper.ts
|
|
497
472
|
async function scrollAtPosition({
|
|
498
473
|
amount,
|
|
499
474
|
direction,
|
|
@@ -530,8 +505,7 @@ async function scrollAtPosition({
|
|
|
530
505
|
}
|
|
531
506
|
}
|
|
532
507
|
|
|
533
|
-
|
|
534
|
-
var DEFAULT_AGENT_WAIT_MS = 3e3;
|
|
508
|
+
const DEFAULT_AGENT_WAIT_MS = 3e3;
|
|
535
509
|
async function execResponse({
|
|
536
510
|
activePage: initialActivePage,
|
|
537
511
|
agentResponse,
|
|
@@ -673,11 +647,10 @@ ${ariaSnapshot}` }
|
|
|
673
647
|
}
|
|
674
648
|
}
|
|
675
649
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
var Agent = class {
|
|
650
|
+
const AGENT_PATH = "internal/v3/agent";
|
|
651
|
+
const STABLY_API_URL$1 = process.env.STABLY_API_URL || "https://api.stably.ai";
|
|
652
|
+
const AGENT_ENDPOINT = new URL(AGENT_PATH, STABLY_API_URL$1).toString();
|
|
653
|
+
class Agent {
|
|
681
654
|
constructor(browserContext) {
|
|
682
655
|
this.browserContext = browserContext;
|
|
683
656
|
}
|
|
@@ -746,13 +719,13 @@ var Agent = class {
|
|
|
746
719
|
newPageOpenedMsg = `opened new tab ${alias} (${page.url()})`;
|
|
747
720
|
};
|
|
748
721
|
this.browserContext.on("page", onNewPage);
|
|
749
|
-
return await
|
|
722
|
+
return await test.step(`[Agent] ${prompt}`, async () => {
|
|
750
723
|
try {
|
|
751
724
|
for (let i = 0; i < maxCycles; i++) {
|
|
752
725
|
if (agentMessage.shouldTerminate) {
|
|
753
726
|
break;
|
|
754
727
|
}
|
|
755
|
-
const agentResponses = await
|
|
728
|
+
const agentResponses = await test.step(`[Thinking ${i + 1}]`, async (stepInfo) => {
|
|
756
729
|
const screenshot = await takeStableScreenshot(activePage);
|
|
757
730
|
const response = await pRetry(
|
|
758
731
|
() => fetch(AGENT_ENDPOINT, {
|
|
@@ -842,22 +815,20 @@ var Agent = class {
|
|
|
842
815
|
}
|
|
843
816
|
});
|
|
844
817
|
}
|
|
845
|
-
}
|
|
846
|
-
|
|
818
|
+
}
|
|
819
|
+
const createNewAgent = (browserContext) => new Agent(browserContext);
|
|
847
820
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
var EXTRACT_ENDPOINT = new URL(EXTRACT_PATH, STABLY_API_URL3).toString();
|
|
853
|
-
var zodV4 = (() => {
|
|
821
|
+
const EXTRACT_PATH = "internal/v2/extract";
|
|
822
|
+
const STABLY_API_URL = process.env.STABLY_API_URL || "https://api.stably.ai";
|
|
823
|
+
const EXTRACT_ENDPOINT = new URL(EXTRACT_PATH, STABLY_API_URL).toString();
|
|
824
|
+
const zodV4 = (() => {
|
|
854
825
|
try {
|
|
855
|
-
return
|
|
826
|
+
return require("zod/v4/core");
|
|
856
827
|
} catch {
|
|
857
828
|
return void 0;
|
|
858
829
|
}
|
|
859
830
|
})();
|
|
860
|
-
|
|
831
|
+
const isExtractionResponse = (value) => {
|
|
861
832
|
if (!isObject(value)) {
|
|
862
833
|
return false;
|
|
863
834
|
}
|
|
@@ -866,16 +837,16 @@ var isExtractionResponse = (value) => {
|
|
|
866
837
|
}
|
|
867
838
|
return value.success === false && typeof value.error === "string";
|
|
868
839
|
};
|
|
869
|
-
|
|
840
|
+
const isErrorResponse = (value) => {
|
|
870
841
|
return isObject(value) && typeof value.error === "string";
|
|
871
842
|
};
|
|
872
|
-
|
|
843
|
+
class ExtractValidationError extends Error {
|
|
873
844
|
constructor(message, issues) {
|
|
874
845
|
super(message);
|
|
875
846
|
this.issues = issues;
|
|
876
847
|
this.name = "ExtractValidationError";
|
|
877
848
|
}
|
|
878
|
-
}
|
|
849
|
+
}
|
|
879
850
|
async function validateWithSchema(schema, value) {
|
|
880
851
|
const result = await schema.safeParseAsync(value);
|
|
881
852
|
if (!result.success) {
|
|
@@ -900,7 +871,7 @@ async function extract({
|
|
|
900
871
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
901
872
|
schema
|
|
902
873
|
) : void 0;
|
|
903
|
-
return await
|
|
874
|
+
return await test.step(`[Extract] ${prompt}`, async (stepInfo) => {
|
|
904
875
|
const apiKey = requireApiKey();
|
|
905
876
|
const form = new FormData();
|
|
906
877
|
form.append("prompt", prompt);
|
|
@@ -943,9 +914,8 @@ async function extract({
|
|
|
943
914
|
});
|
|
944
915
|
}
|
|
945
916
|
|
|
946
|
-
// src/playwright-augment/methods/extract.ts
|
|
947
917
|
function createExtract(pageOrLocator) {
|
|
948
|
-
const impl = async (prompt, options) => {
|
|
918
|
+
const impl = (async (prompt, options) => {
|
|
949
919
|
if (options?.schema) {
|
|
950
920
|
return extract({
|
|
951
921
|
pageOrLocator,
|
|
@@ -954,18 +924,17 @@ function createExtract(pageOrLocator) {
|
|
|
954
924
|
});
|
|
955
925
|
}
|
|
956
926
|
return extract({ pageOrLocator, prompt });
|
|
957
|
-
};
|
|
927
|
+
});
|
|
958
928
|
return impl;
|
|
959
929
|
}
|
|
960
|
-
|
|
961
|
-
|
|
930
|
+
const createLocatorExtract = (locator) => createExtract(locator);
|
|
931
|
+
const createPageExtract = (page) => createExtract(page);
|
|
962
932
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
var BROWSER_TYPE_PATCHED = Symbol.for("stably.playwright.browserTypePatched");
|
|
933
|
+
const LOCATOR_PATCHED = Symbol.for("stably.playwright.locatorPatched");
|
|
934
|
+
const PAGE_PATCHED = Symbol.for("stably.playwright.pagePatched");
|
|
935
|
+
const CONTEXT_PATCHED = Symbol.for("stably.playwright.contextPatched");
|
|
936
|
+
const BROWSER_PATCHED = Symbol.for("stably.playwright.browserPatched");
|
|
937
|
+
const BROWSER_TYPE_PATCHED = Symbol.for("stably.playwright.browserTypePatched");
|
|
969
938
|
function defineHiddenProperty(target, key, value) {
|
|
970
939
|
Object.defineProperty(target, key, {
|
|
971
940
|
configurable: true,
|
|
@@ -987,10 +956,10 @@ function augmentPage(page) {
|
|
|
987
956
|
return page;
|
|
988
957
|
}
|
|
989
958
|
const originalLocator = page.locator.bind(page);
|
|
990
|
-
page.locator = (...args) => {
|
|
959
|
+
page.locator = ((...args) => {
|
|
991
960
|
const locator = originalLocator(...args);
|
|
992
961
|
return augmentLocator(locator);
|
|
993
|
-
};
|
|
962
|
+
});
|
|
994
963
|
defineHiddenProperty(page, "extract", createPageExtract(page));
|
|
995
964
|
defineHiddenProperty(page, PAGE_PATCHED, true);
|
|
996
965
|
return page;
|
|
@@ -1000,13 +969,13 @@ function augmentBrowserContext(context) {
|
|
|
1000
969
|
return context;
|
|
1001
970
|
}
|
|
1002
971
|
const originalNewPage = context.newPage.bind(context);
|
|
1003
|
-
context.newPage = async (...args) => {
|
|
972
|
+
context.newPage = (async (...args) => {
|
|
1004
973
|
const page = await originalNewPage(...args);
|
|
1005
974
|
return augmentPage(page);
|
|
1006
|
-
};
|
|
975
|
+
});
|
|
1007
976
|
const originalPages = context.pages?.bind(context);
|
|
1008
977
|
if (originalPages) {
|
|
1009
|
-
context.pages = () => originalPages().map((page) => augmentPage(page));
|
|
978
|
+
context.pages = (() => originalPages().map((page) => augmentPage(page)));
|
|
1010
979
|
}
|
|
1011
980
|
if (!context.newAgent) {
|
|
1012
981
|
defineHiddenProperty(context, "newAgent", () => {
|
|
@@ -1021,19 +990,19 @@ function augmentBrowser(browser) {
|
|
|
1021
990
|
return browser;
|
|
1022
991
|
}
|
|
1023
992
|
const originalNewContext = browser.newContext.bind(browser);
|
|
1024
|
-
browser.newContext = async (...args) => {
|
|
993
|
+
browser.newContext = (async (...args) => {
|
|
1025
994
|
const context = await originalNewContext(...args);
|
|
1026
995
|
return augmentBrowserContext(context);
|
|
1027
|
-
};
|
|
996
|
+
});
|
|
1028
997
|
const originalNewPage = browser.newPage.bind(browser);
|
|
1029
|
-
browser.newPage = async (...args) => {
|
|
998
|
+
browser.newPage = (async (...args) => {
|
|
1030
999
|
const page = await originalNewPage(...args);
|
|
1031
1000
|
return augmentPage(page);
|
|
1032
|
-
};
|
|
1001
|
+
});
|
|
1033
1002
|
const originalContexts = browser.contexts.bind(browser);
|
|
1034
|
-
browser.contexts = () => originalContexts().map(
|
|
1003
|
+
browser.contexts = (() => originalContexts().map(
|
|
1035
1004
|
(context) => augmentBrowserContext(context)
|
|
1036
|
-
);
|
|
1005
|
+
));
|
|
1037
1006
|
if (!browser.newAgent) {
|
|
1038
1007
|
defineHiddenProperty(browser, "newAgent", () => {
|
|
1039
1008
|
const contexts = browser.contexts();
|
|
@@ -1049,45 +1018,36 @@ function augmentBrowserType(browserType) {
|
|
|
1049
1018
|
return browserType;
|
|
1050
1019
|
}
|
|
1051
1020
|
const originalLaunch = browserType.launch.bind(browserType);
|
|
1052
|
-
browserType.launch = async (...args) => {
|
|
1021
|
+
browserType.launch = (async (...args) => {
|
|
1053
1022
|
const browser = await originalLaunch(...args);
|
|
1054
1023
|
return augmentBrowser(browser);
|
|
1055
|
-
};
|
|
1024
|
+
});
|
|
1056
1025
|
const originalConnect = browserType.connect?.bind(browserType);
|
|
1057
1026
|
if (originalConnect) {
|
|
1058
|
-
browserType.connect = async (...args) => {
|
|
1027
|
+
browserType.connect = (async (...args) => {
|
|
1059
1028
|
const browser = await originalConnect(...args);
|
|
1060
1029
|
return augmentBrowser(browser);
|
|
1061
|
-
};
|
|
1030
|
+
});
|
|
1062
1031
|
}
|
|
1063
1032
|
const originalConnectOverCDP = browserType.connectOverCDP?.bind(
|
|
1064
1033
|
browserType
|
|
1065
1034
|
);
|
|
1066
1035
|
if (originalConnectOverCDP) {
|
|
1067
|
-
browserType.connectOverCDP = async (...args) => {
|
|
1036
|
+
browserType.connectOverCDP = (async (...args) => {
|
|
1068
1037
|
const browser = await originalConnectOverCDP(...args);
|
|
1069
1038
|
return augmentBrowser(browser);
|
|
1070
|
-
};
|
|
1039
|
+
});
|
|
1071
1040
|
}
|
|
1072
1041
|
const originalLaunchPersistentContext = browserType.launchPersistentContext?.bind(browserType);
|
|
1073
1042
|
if (originalLaunchPersistentContext) {
|
|
1074
|
-
browserType.launchPersistentContext = async (...args) => {
|
|
1043
|
+
browserType.launchPersistentContext = (async (...args) => {
|
|
1075
1044
|
const context = await originalLaunchPersistentContext(...args);
|
|
1076
1045
|
return augmentBrowserContext(context);
|
|
1077
|
-
};
|
|
1046
|
+
});
|
|
1078
1047
|
}
|
|
1079
1048
|
defineHiddenProperty(browserType, BROWSER_TYPE_PATCHED, true);
|
|
1080
1049
|
return browserType;
|
|
1081
1050
|
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
augmentBrowserContext,
|
|
1086
|
-
augmentBrowserType,
|
|
1087
|
-
augmentLocator,
|
|
1088
|
-
augmentPage,
|
|
1089
|
-
requireApiKey,
|
|
1090
|
-
setApiKey,
|
|
1091
|
-
stablyPlaywrightMatchers
|
|
1092
|
-
};
|
|
1093
|
-
//# sourceMappingURL=index.mjs.map
|
|
1051
|
+
|
|
1052
|
+
export { Agent, augmentBrowser, augmentBrowserContext, augmentBrowserType, augmentLocator, augmentPage, requireApiKey, setApiKey, stablyPlaywrightMatchers };
|
|
1053
|
+
//# sourceMappingURL=index.mjs.map
|