@probolabs/playwright 0.4.20 → 1.0.1
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/README.md +136 -136
- package/dist/index.d.ts +67 -21
- package/dist/index.js +378 -615
- package/dist/index.js.map +1 -1
- package/dist/types/actions.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/nav-tracker.d.ts.map +1 -0
- package/dist/types/replay-utils.d.ts.map +1 -1
- package/dist/types/workspaceScriptRunner.d.ts.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
# Probolib: drive your playwright scripts with AI superpowers
|
|
2
|
-
|
|
3
|
-
Probolib is a powerful AI-driven automation library that enhances Playwright testing and automation by making your scripts more robust and maintainable. Instead of relying on brittle CSS selectors or complex XPath expressions, Probolib uses natural language to interact with web elements.
|
|
4
|
-
|
|
5
|
-
## Why Probolib?
|
|
6
|
-
|
|
7
|
-
- **Natural Language Automation**: Write human-readable instructions instead of complex selectors
|
|
8
|
-
- **More Resilient Tests**: AI-powered element detection that adapts to UI changes
|
|
9
|
-
- **Simpler Maintenance**: Reduce the need to update selectors when the UI changes
|
|
10
|
-
- **Faster Development**: Write automation scripts in plain English
|
|
11
|
-
|
|
12
|
-
## Example
|
|
13
|
-
|
|
14
|
-
Instead of writing:
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
page.click('some > super > complex > css > and non robust selector')
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
You can simply write:
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
probo.runStep(page, 'click on the save button')
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Quickstart
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
npm install @probolabs/playwright
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Accessing our backend
|
|
33
|
-
|
|
34
|
-
the heavy lifting of the AI reasoning is done at the moment on our backend server. in order to access it you would need to tell the library how to access it.
|
|
35
|
-
|
|
36
|
-
## easyiest - set ENV var
|
|
37
|
-
|
|
38
|
-
probolib expects the existance of 2 env vars:
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
export PROBO_API_ENDPOINT=api.probolabs.ai
|
|
42
|
-
export PROBO_API_KEY=<api key we will give you>
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Or use dotenv
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
// npm install dotenv
|
|
50
|
-
// in your script add this line
|
|
51
|
-
import 'dotenv/config' // ES6
|
|
52
|
-
|
|
53
|
-
// .env file located in the root of your project (the same level as your package.json)
|
|
54
|
-
PROBO_API_ENDPOINT=https://api.probolabs.ai
|
|
55
|
-
PROBO_API_KEY=<api key we will give you>
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## A complete example for Playwright integration. step by step
|
|
60
|
-
|
|
61
|
-
**step 1:** init a playwright project
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
# from your work directory
|
|
65
|
-
mkdir probo-example
|
|
66
|
-
cd probo-example
|
|
67
|
-
npm init playwright@latest
|
|
68
|
-
# follow the instructions and wait till the installation is finished
|
|
69
|
-
# verify that playwright is installed properly
|
|
70
|
-
npx playwright test --project chromium
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**step 2**: integrate probolabs
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
npm install @probolabs/playwright dotenv
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**step 3:** configure the env with our endpoint and api key
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
touch .env
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
edit the .env file
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
#.env
|
|
89
|
-
PROBO_API_ENDPOINT=https://api.probolabs.ai
|
|
90
|
-
PROBO_API_KEY=<api key we will give you>
|
|
91
|
-
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**step 4:** create a file under the tests folder named `probo-example-todo-mvc.spec.mjs`
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
// tests/probo-example-todo-mvc.spec.mjs
|
|
98
|
-
import 'dotenv/config';
|
|
99
|
-
import { test} from '@playwright/test';
|
|
100
|
-
import { Probo } from '@probolabs/playwright';
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
// Important: Before running this script set PROBO_API_KEY and PROBO_API_ENDPOINT
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
test.describe('Todo MVC', () => {
|
|
107
|
-
test('basic example', async ({ page }) => {
|
|
108
|
-
try {
|
|
109
|
-
// Initialize Probo
|
|
110
|
-
const probo = new Probo({
|
|
111
|
-
scenarioName: 'probo-example-todo-mvc' // important for caching the AI reasoning
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
//Goto page
|
|
115
|
-
await page.goto('https://demo.playwright.dev/todomvc');
|
|
116
|
-
|
|
117
|
-
// Run test steps
|
|
118
|
-
console.log('Running test steps...');
|
|
119
|
-
await probo.runStep(page, 'enter a new todo item: "Buy groceries"');
|
|
120
|
-
await probo.runStep(page, 'press the Enter key');
|
|
121
|
-
|
|
122
|
-
console.log('✨ Test completed successfully!');
|
|
123
|
-
} catch (error) {
|
|
124
|
-
console.error('❌ Test failed:', error);
|
|
125
|
-
throw error; // Re-throw to mark the test as failed
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
**run the example**
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
npx playwright test tests/probo-example-todo-mvc.spec.mjs --headed --project chromium
|
|
136
|
-
```
|
|
1
|
+
# Probolib: drive your playwright scripts with AI superpowers
|
|
2
|
+
|
|
3
|
+
Probolib is a powerful AI-driven automation library that enhances Playwright testing and automation by making your scripts more robust and maintainable. Instead of relying on brittle CSS selectors or complex XPath expressions, Probolib uses natural language to interact with web elements.
|
|
4
|
+
|
|
5
|
+
## Why Probolib?
|
|
6
|
+
|
|
7
|
+
- **Natural Language Automation**: Write human-readable instructions instead of complex selectors
|
|
8
|
+
- **More Resilient Tests**: AI-powered element detection that adapts to UI changes
|
|
9
|
+
- **Simpler Maintenance**: Reduce the need to update selectors when the UI changes
|
|
10
|
+
- **Faster Development**: Write automation scripts in plain English
|
|
11
|
+
|
|
12
|
+
## Example
|
|
13
|
+
|
|
14
|
+
Instead of writing:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
page.click('some > super > complex > css > and non robust selector')
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
You can simply write:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
probo.runStep(page, 'click on the save button')
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quickstart
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
npm install @probolabs/playwright
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Accessing our backend
|
|
33
|
+
|
|
34
|
+
the heavy lifting of the AI reasoning is done at the moment on our backend server. in order to access it you would need to tell the library how to access it.
|
|
35
|
+
|
|
36
|
+
## easyiest - set ENV var
|
|
37
|
+
|
|
38
|
+
probolib expects the existance of 2 env vars:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
export PROBO_API_ENDPOINT=api.probolabs.ai
|
|
42
|
+
export PROBO_API_KEY=<api key we will give you>
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or use dotenv
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
// npm install dotenv
|
|
50
|
+
// in your script add this line
|
|
51
|
+
import 'dotenv/config' // ES6
|
|
52
|
+
|
|
53
|
+
// .env file located in the root of your project (the same level as your package.json)
|
|
54
|
+
PROBO_API_ENDPOINT=https://api.probolabs.ai
|
|
55
|
+
PROBO_API_KEY=<api key we will give you>
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## A complete example for Playwright integration. step by step
|
|
60
|
+
|
|
61
|
+
**step 1:** init a playwright project
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
# from your work directory
|
|
65
|
+
mkdir probo-example
|
|
66
|
+
cd probo-example
|
|
67
|
+
npm init playwright@latest
|
|
68
|
+
# follow the instructions and wait till the installation is finished
|
|
69
|
+
# verify that playwright is installed properly
|
|
70
|
+
npx playwright test --project chromium
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**step 2**: integrate probolabs
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
npm install @probolabs/playwright dotenv
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**step 3:** configure the env with our endpoint and api key
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
touch .env
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
edit the .env file
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
#.env
|
|
89
|
+
PROBO_API_ENDPOINT=https://api.probolabs.ai
|
|
90
|
+
PROBO_API_KEY=<api key we will give you>
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**step 4:** create a file under the tests folder named `probo-example-todo-mvc.spec.mjs`
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
// tests/probo-example-todo-mvc.spec.mjs
|
|
98
|
+
import 'dotenv/config';
|
|
99
|
+
import { test} from '@playwright/test';
|
|
100
|
+
import { Probo } from '@probolabs/playwright';
|
|
101
|
+
|
|
102
|
+
//
|
|
103
|
+
// Important: Before running this script set PROBO_API_KEY and PROBO_API_ENDPOINT
|
|
104
|
+
//
|
|
105
|
+
|
|
106
|
+
test.describe('Todo MVC', () => {
|
|
107
|
+
test('basic example', async ({ page }) => {
|
|
108
|
+
try {
|
|
109
|
+
// Initialize Probo
|
|
110
|
+
const probo = new Probo({
|
|
111
|
+
scenarioName: 'probo-example-todo-mvc' // important for caching the AI reasoning
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
//Goto page
|
|
115
|
+
await page.goto('https://demo.playwright.dev/todomvc');
|
|
116
|
+
|
|
117
|
+
// Run test steps
|
|
118
|
+
console.log('Running test steps...');
|
|
119
|
+
await probo.runStep(page, 'enter a new todo item: "Buy groceries"');
|
|
120
|
+
await probo.runStep(page, 'press the Enter key');
|
|
121
|
+
|
|
122
|
+
console.log('✨ Test completed successfully!');
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.error('❌ Test failed:', error);
|
|
125
|
+
throw error; // Re-throw to mark the test as failed
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**run the example**
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
npx playwright test tests/probo-example-todo-mvc.spec.mjs --headed --project chromium
|
|
136
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Locator, Page } from 'playwright';
|
|
2
|
+
import { ElementTag, PlaywrightTimeoutConfig, PlaywrightAction, AIModel, InitialPageState, FindCandidateInput, ServerResponse, ProboLogLevel } from '@probolabs/probo-shared';
|
|
3
3
|
export { ElementInfo, ElementTag, PlaywrightAction, ProboLogLevel } from '@probolabs/probo-shared';
|
|
4
4
|
import { Page as Page$1 } from '@playwright/test';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Execute a given Playwright action, mirroring Python's _perform_action
|
|
8
|
-
*/
|
|
9
|
-
declare function executePlaywrightAction(page: Page, action: PlaywrightAction, value: string | boolean, iframe_selector: string, element_css_selector: string): Promise<boolean | string>;
|
|
10
|
-
/**
|
|
11
|
-
* Execute a given Playwright action using native Playwright functions where possible
|
|
12
|
-
*/
|
|
13
|
-
declare function executeCachedPlaywrightAction(page: Page, action: PlaywrightAction, value: string | boolean, iframe_selector: string, element_css_selector: string): Promise<boolean | string>;
|
|
14
6
|
/**
|
|
15
7
|
* Traverses up the DOM from the given locator to find the closest visible ancestor.
|
|
16
8
|
* Returns a Locator for the first visible element found, or null if none is visible up to <html>.
|
|
@@ -97,19 +89,18 @@ declare class Highlighter {
|
|
|
97
89
|
}
|
|
98
90
|
|
|
99
91
|
interface RunStepParams extends Partial<PlaywrightTimeoutConfig> {
|
|
100
|
-
iframeSelector
|
|
101
|
-
elementSelector
|
|
102
|
-
action: PlaywrightAction
|
|
92
|
+
iframeSelector?: string;
|
|
93
|
+
elementSelector?: string;
|
|
94
|
+
action: PlaywrightAction;
|
|
103
95
|
argument?: string | string[];
|
|
104
96
|
annotation?: string;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
key: string;
|
|
108
|
-
value: any;
|
|
97
|
+
pollingInterval?: number;
|
|
98
|
+
timeout?: number;
|
|
109
99
|
}
|
|
110
100
|
declare class ProboPlaywright {
|
|
111
101
|
private readonly config;
|
|
112
102
|
private page;
|
|
103
|
+
private lastNavigationTime;
|
|
113
104
|
constructor(config?: PlaywrightTimeoutConfig, page?: Page$1 | null);
|
|
114
105
|
/**
|
|
115
106
|
* Sets the Playwright page instance for this ProboPlaywright instance.
|
|
@@ -118,6 +109,7 @@ declare class ProboPlaywright {
|
|
|
118
109
|
* @param page - The Playwright Page instance to use, or null to unset.
|
|
119
110
|
*/
|
|
120
111
|
setPage(page: Page$1 | null): void;
|
|
112
|
+
private onFrameNav;
|
|
121
113
|
/**
|
|
122
114
|
* Executes a single step in the test scenario with the specified action on the target element.
|
|
123
115
|
* Handles iframe navigation, element highlighting, and various Playwright actions like click, fill, validate, etc.
|
|
@@ -126,7 +118,7 @@ declare class ProboPlaywright {
|
|
|
126
118
|
* @returns Promise that resolves to a result object for extract actions, or void for other actions
|
|
127
119
|
* @throws Error if element is not found or validation fails
|
|
128
120
|
*/
|
|
129
|
-
runStep(params: RunStepParams): Promise<
|
|
121
|
+
runStep(params: RunStepParams): Promise<string | void>;
|
|
130
122
|
/**
|
|
131
123
|
* Creates a visual highlight overlay on the target element with optional annotation text.
|
|
132
124
|
* The highlight appears as a red border around the element and can include descriptive text.
|
|
@@ -169,6 +161,55 @@ declare class ProboPlaywright {
|
|
|
169
161
|
private getTextValue;
|
|
170
162
|
}
|
|
171
163
|
|
|
164
|
+
interface NavTrackerOptions {
|
|
165
|
+
stabilizationTimeout?: number;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Global navigation tracker that monitors page navigation events
|
|
169
|
+
* and provides methods to check if navigation has stabilized
|
|
170
|
+
*
|
|
171
|
+
* This is a singleton class - only one instance can exist at a time
|
|
172
|
+
*/
|
|
173
|
+
declare class NavTracker {
|
|
174
|
+
private static instance;
|
|
175
|
+
private page;
|
|
176
|
+
private navigationCount;
|
|
177
|
+
private lastNavTime;
|
|
178
|
+
private stabilizationTimeout;
|
|
179
|
+
private isListening;
|
|
180
|
+
private onFrameNavHandler;
|
|
181
|
+
private instanceId;
|
|
182
|
+
/**
|
|
183
|
+
* Private constructor - use getInstance() to get the singleton instance
|
|
184
|
+
*/
|
|
185
|
+
private constructor();
|
|
186
|
+
/**
|
|
187
|
+
* Start listening for navigation events (private method)
|
|
188
|
+
*/
|
|
189
|
+
private start;
|
|
190
|
+
/**
|
|
191
|
+
* Stop listening for navigation events (private method)
|
|
192
|
+
*/
|
|
193
|
+
private stop;
|
|
194
|
+
/**
|
|
195
|
+
* Check if navigation has stabilized (no navigation for stabilizationTimeout ms) (private method)
|
|
196
|
+
*/
|
|
197
|
+
private hasNavigationStabilized;
|
|
198
|
+
/**
|
|
199
|
+
* Wait for navigation to stabilize
|
|
200
|
+
* Waits a short time to catch any missed navigation events, then ensures
|
|
201
|
+
* the latest navigation happened at least stabilizationTimeout ms ago
|
|
202
|
+
*/
|
|
203
|
+
waitForNavigationToStabilize(): Promise<void>;
|
|
204
|
+
/**
|
|
205
|
+
* Get the singleton instance of NavTracker
|
|
206
|
+
* @param page The page to track (required for first creation)
|
|
207
|
+
* @param options Optional configuration
|
|
208
|
+
* @returns The singleton NavTracker instance
|
|
209
|
+
*/
|
|
210
|
+
static getInstance(page?: Page, options?: NavTrackerOptions): NavTracker;
|
|
211
|
+
}
|
|
212
|
+
|
|
172
213
|
/**
|
|
173
214
|
* Configuration options for Probo client
|
|
174
215
|
*/
|
|
@@ -181,11 +222,13 @@ interface ProboConfig {
|
|
|
181
222
|
logToFile?: boolean;
|
|
182
223
|
debugLevel?: ProboLogLevel;
|
|
183
224
|
aiModel?: AIModel;
|
|
225
|
+
timeoutConfig?: PlaywrightTimeoutConfig;
|
|
184
226
|
}
|
|
185
227
|
interface RunStepOptions {
|
|
186
228
|
useCache: boolean;
|
|
187
229
|
stepIdFromServer?: number | null;
|
|
188
230
|
aiModel?: AIModel;
|
|
231
|
+
timeoutConfig?: PlaywrightTimeoutConfig;
|
|
189
232
|
}
|
|
190
233
|
declare class Probo {
|
|
191
234
|
private highlighter;
|
|
@@ -193,12 +236,15 @@ declare class Probo {
|
|
|
193
236
|
private readonly enableConsoleLogs;
|
|
194
237
|
private readonly scenarioName;
|
|
195
238
|
private readonly aiModel;
|
|
196
|
-
|
|
239
|
+
private readonly timeoutConfig;
|
|
240
|
+
constructor({ scenarioName, token, apiUrl, enableConsoleLogs, logToConsole, logToFile, debugLevel, aiModel, timeoutConfig }: ProboConfig);
|
|
197
241
|
askAI(page: Page, question: string): Promise<any>;
|
|
198
|
-
runStep(page: Page, stepPrompt: string, argument?: string | boolean | null, options?: RunStepOptions): Promise<boolean | string>;
|
|
242
|
+
runStep(page: Page, stepPrompt: string, argument?: string | boolean | null, options?: RunStepOptions): Promise<boolean | string | null>;
|
|
199
243
|
private _handleCachedStep;
|
|
200
244
|
private _handleStepCreation;
|
|
201
245
|
private setupConsoleLogs;
|
|
246
|
+
getInitialPageState(page: Page): Promise<InitialPageState>;
|
|
247
|
+
findAndHighlightCandidateElements(page: Page, elementTags: string[]): Promise<FindCandidateInput>;
|
|
202
248
|
highlightElements(page: Page, elementTags: [ElementTagType]): Promise<any>;
|
|
203
249
|
unhighlightElements(page: Page): Promise<void>;
|
|
204
250
|
highlightElement(page: Page, element_css_selector: string, iframe_selector: string, element_index: string): Promise<void>;
|
|
@@ -208,5 +254,5 @@ declare class Probo {
|
|
|
208
254
|
askAIHelper(page: Page, question: string): Promise<ServerResponse>;
|
|
209
255
|
}
|
|
210
256
|
|
|
211
|
-
export { Highlighter, Probo, ProboPlaywright,
|
|
257
|
+
export { Highlighter, NavTracker, Probo, ProboPlaywright, findClosestVisibleElement };
|
|
212
258
|
export type { ElementTagType, RunStepOptions };
|