@probolabs/playwright 0.4.16 → 0.4.18
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 +63 -41
- package/dist/index.js +1238 -1024
- package/dist/index.js.map +1 -1
- package/dist/types/actions.d.ts.map +1 -1
- package/dist/types/highlight.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/probo-logger.d.ts.map +1 -0
- package/package.json +5 -4
- package/dist/types/api-client.d.ts.map +0 -1
- package/dist/types/utils.d.ts.map +0 -1
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,6 +1,15 @@
|
|
|
1
1
|
import { Page } from 'playwright';
|
|
2
|
-
import { ElementTag } from '@probolabs/
|
|
3
|
-
export { ElementInfo, ElementTag } from '@probolabs/
|
|
2
|
+
import { PlaywrightAction, ElementTag, ProboLogLevel } from '@probolabs/probo-shared';
|
|
3
|
+
export { ElementInfo, ElementTag, PlaywrightAction, ProboLogLevel } from '@probolabs/probo-shared';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Execute a given Playwright action, mirroring Python's _perform_action
|
|
7
|
+
*/
|
|
8
|
+
declare function executePlaywrightAction(page: Page, action: PlaywrightAction, value: string, iframe_selector: string, element_css_selector: string): Promise<boolean>;
|
|
9
|
+
/**
|
|
10
|
+
* Execute a given Playwright action using native Playwright functions where possible
|
|
11
|
+
*/
|
|
12
|
+
declare function executeCachedPlaywrightAction(page: Page, action: PlaywrightAction, value: string, iframe_selector: string, element_css_selector: string): Promise<boolean>;
|
|
4
13
|
|
|
5
14
|
type ElementTagType = typeof ElementTag[keyof typeof ElementTag];
|
|
6
15
|
declare global {
|
|
@@ -16,7 +25,22 @@ declare global {
|
|
|
16
25
|
iframe_selector: string;
|
|
17
26
|
index: string;
|
|
18
27
|
}>) => void;
|
|
28
|
+
unhighlightElements: () => void;
|
|
29
|
+
findElements: (elementTypes: string) => any[];
|
|
30
|
+
getElementInfo: (element: Element, index: number) => any;
|
|
19
31
|
ElementTag: typeof ElementTag;
|
|
32
|
+
candidates?: any[];
|
|
33
|
+
actual?: any;
|
|
34
|
+
matchingCandidate?: any;
|
|
35
|
+
findAndCacheCandidateElements?: (elementTypes: string[]) => number;
|
|
36
|
+
findAndCacheActualElement?: (cssSelector: string, iframeSelector: string | null, isHover: boolean) => boolean;
|
|
37
|
+
findAndCacheMatchingCandidate?: () => boolean;
|
|
38
|
+
highlightCachedElements?: (which: 'candidates' | 'actual' | 'matching') => void;
|
|
39
|
+
unhighlight?: () => void;
|
|
40
|
+
reset?: () => void;
|
|
41
|
+
getCandidates?: () => any[];
|
|
42
|
+
getActual?: () => any;
|
|
43
|
+
getMatchingCandidate?: () => any;
|
|
20
44
|
};
|
|
21
45
|
}
|
|
22
46
|
}
|
|
@@ -27,43 +51,40 @@ declare class Highlighter {
|
|
|
27
51
|
highlightElements(page: Page, elementTags: [ElementTagType]): Promise<any>;
|
|
28
52
|
unhighlightElements(page: Page): Promise<void>;
|
|
29
53
|
highlightElement(page: Page, element_css_selector: string, iframe_selector: string, element_index: string): Promise<void>;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
log(...args: any[]): void;
|
|
65
|
-
warn(...args: any[]): void;
|
|
66
|
-
error(...args: any[]): void;
|
|
54
|
+
/**
|
|
55
|
+
* Find and cache candidate elements of a given type (e.g., 'CLICKABLE').
|
|
56
|
+
* Returns the number of candidates found.
|
|
57
|
+
*/
|
|
58
|
+
findAndCacheCandidateElements(page: Page, elementTypes: string[]): Promise<number>;
|
|
59
|
+
/**
|
|
60
|
+
* Find and cache the actual interaction element by CSS and iframe selector.
|
|
61
|
+
* Returns true if found, false otherwise.
|
|
62
|
+
*/
|
|
63
|
+
findAndCacheActualElement(page: Page, cssSelector: string, iframeSelector: string | null, isHover?: boolean): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Find and cache the best matching candidate for the actual element.
|
|
66
|
+
* Returns true if a match was found, false otherwise.
|
|
67
|
+
*/
|
|
68
|
+
findAndCacheMatchingCandidate(page: Page): Promise<boolean>;
|
|
69
|
+
/**
|
|
70
|
+
* Highlight the cached candidates, actual, or matching candidate.
|
|
71
|
+
* @param which 'candidates' | 'actual' | 'matching'
|
|
72
|
+
*/
|
|
73
|
+
highlightCachedElements(page: Page, which: 'candidates' | 'actual' | 'matching'): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Remove all highlights.
|
|
76
|
+
*/
|
|
77
|
+
unhighlightCached(page: Page): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Reset/clear all cached state.
|
|
80
|
+
*/
|
|
81
|
+
resetCached(page: Page): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Get serializable info for Node/Playwright (candidates, actual, matchingCandidate)
|
|
84
|
+
*/
|
|
85
|
+
getCandidatesCached(page: Page): Promise<any[] | undefined>;
|
|
86
|
+
getActualCached(page: Page): Promise<any>;
|
|
87
|
+
getMatchingCandidateCached(page: Page): Promise<any>;
|
|
67
88
|
}
|
|
68
89
|
|
|
69
90
|
/**
|
|
@@ -107,7 +128,7 @@ declare class Probo {
|
|
|
107
128
|
private readonly scenarioName;
|
|
108
129
|
private readonly aiModel;
|
|
109
130
|
constructor({ scenarioName, token, apiUrl, enableConsoleLogs, logToConsole, logToFile, debugLevel, aiModel }: ProboConfig);
|
|
110
|
-
runStep(page: Page, stepPrompt: string, options?: RunStepOptions): Promise<boolean>;
|
|
131
|
+
runStep(page: Page, stepPrompt: string, argument?: string | null, options?: RunStepOptions): Promise<boolean>;
|
|
111
132
|
private _handleCachedStep;
|
|
112
133
|
private _handleStepCreation;
|
|
113
134
|
private setupConsoleLogs;
|
|
@@ -118,4 +139,5 @@ declare class Probo {
|
|
|
118
139
|
private _handlePerformAction;
|
|
119
140
|
}
|
|
120
141
|
|
|
121
|
-
export { AIModel,
|
|
142
|
+
export { AIModel, Highlighter, Probo, executeCachedPlaywrightAction, executePlaywrightAction };
|
|
143
|
+
export type { ElementTagType, RunStepOptions };
|