@probolabs/playwright 1.0.12 → 1.0.16
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 +227 -227
- package/dist/fixtures.js +6 -1
- package/dist/fixtures.js.map +1 -1
- package/dist/index.d.ts +35 -14
- package/dist/index.js +1197 -1084
- package/dist/index.js.map +1 -1
- package/dist/types/fixtures.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/otp.d.ts.map +1 -1
- package/dist/types/replay-utils.d.ts.map +1 -1
- package/loaded_extensions/README.md +23 -23
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,227 +1,227 @@
|
|
|
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
|
-
```
|
|
137
|
-
|
|
138
|
-
## Using Probo Fixtures (Connect to Existing Browser)
|
|
139
|
-
|
|
140
|
-
Probo fixtures allow you to connect to an existing Chrome instance (like your recorder app) instead of launching a new browser. This is useful when you want to run tests against a browser that's already running with specific extensions or configurations.
|
|
141
|
-
|
|
142
|
-
### Quick Setup
|
|
143
|
-
|
|
144
|
-
**Step 1:** Install the package
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
npm install @probolabs/playwright
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**Step 2:** Create a `playwright.config.ts` file
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
// playwright.config.ts
|
|
154
|
-
import { defineConfig } from "@playwright/test";
|
|
155
|
-
|
|
156
|
-
export default defineConfig({
|
|
157
|
-
testDir: "./tests",
|
|
158
|
-
use: {
|
|
159
|
-
// Don't launch a new browser - Probo fixtures will connect to existing one
|
|
160
|
-
launchOptions: {},
|
|
161
|
-
},
|
|
162
|
-
workers: 1, // Use 1 worker to avoid conflicts with existing browser
|
|
163
|
-
});
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
**Step 3:** Use Probo fixtures in your test files
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
// tests/example.spec.ts
|
|
170
|
-
import { test, expect } from "@probolabs/playwright/fixtures";
|
|
171
|
-
|
|
172
|
-
test.describe("My Tests", () => {
|
|
173
|
-
test("should work with existing browser", async ({ page }) => {
|
|
174
|
-
// This page comes from your existing Chrome instance
|
|
175
|
-
await page.goto("https://example.com");
|
|
176
|
-
await page.click("button");
|
|
177
|
-
|
|
178
|
-
// Your test code here...
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
**Step 4:** Make sure your recorder app is running, then run tests
|
|
184
|
-
|
|
185
|
-
```bash
|
|
186
|
-
npx playwright test
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Advanced Configuration
|
|
190
|
-
|
|
191
|
-
You can customize the fixtures with different options:
|
|
192
|
-
|
|
193
|
-
```typescript
|
|
194
|
-
// tests/example.spec.ts
|
|
195
|
-
import { createProboFixtures, expect } from "@probolabs/playwright/fixtures";
|
|
196
|
-
|
|
197
|
-
// Create custom fixtures with specific configuration
|
|
198
|
-
const test = createProboFixtures({
|
|
199
|
-
debugPort: 9333, // Default port where your recorder app runs
|
|
200
|
-
showBrowserConsole: true, // Show browser console logs
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test.describe("My Tests", () => {
|
|
204
|
-
test("custom configuration", async ({ page }) => {
|
|
205
|
-
// Your test code here...
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Requirements
|
|
211
|
-
|
|
212
|
-
- Your recorder app must be running with Chrome accessible via CDP
|
|
213
|
-
- Chrome must be launched with `--remote-debugging-port=9333` (or your custom port)
|
|
214
|
-
- The browser must have at least one page open (not just extension pages)
|
|
215
|
-
|
|
216
|
-
### Troubleshooting
|
|
217
|
-
|
|
218
|
-
**Error: "No browser context found"**
|
|
219
|
-
|
|
220
|
-
- Make sure your recorder app is running
|
|
221
|
-
- Check that Chrome is accessible at `http://localhost:9333`
|
|
222
|
-
- Verify the debug port matches your configuration
|
|
223
|
-
|
|
224
|
-
**Error: "No main page found"**
|
|
225
|
-
|
|
226
|
-
- Make sure your recorder app has opened a page
|
|
227
|
-
- The page should not be a chrome-extension:// URL
|
|
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
|
+
```
|
|
137
|
+
|
|
138
|
+
## Using Probo Fixtures (Connect to Existing Browser)
|
|
139
|
+
|
|
140
|
+
Probo fixtures allow you to connect to an existing Chrome instance (like your recorder app) instead of launching a new browser. This is useful when you want to run tests against a browser that's already running with specific extensions or configurations.
|
|
141
|
+
|
|
142
|
+
### Quick Setup
|
|
143
|
+
|
|
144
|
+
**Step 1:** Install the package
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm install @probolabs/playwright
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Step 2:** Create a `playwright.config.ts` file
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// playwright.config.ts
|
|
154
|
+
import { defineConfig } from "@playwright/test";
|
|
155
|
+
|
|
156
|
+
export default defineConfig({
|
|
157
|
+
testDir: "./tests",
|
|
158
|
+
use: {
|
|
159
|
+
// Don't launch a new browser - Probo fixtures will connect to existing one
|
|
160
|
+
launchOptions: {},
|
|
161
|
+
},
|
|
162
|
+
workers: 1, // Use 1 worker to avoid conflicts with existing browser
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Step 3:** Use Probo fixtures in your test files
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
// tests/example.spec.ts
|
|
170
|
+
import { test, expect } from "@probolabs/playwright/fixtures";
|
|
171
|
+
|
|
172
|
+
test.describe("My Tests", () => {
|
|
173
|
+
test("should work with existing browser", async ({ page }) => {
|
|
174
|
+
// This page comes from your existing Chrome instance
|
|
175
|
+
await page.goto("https://example.com");
|
|
176
|
+
await page.click("button");
|
|
177
|
+
|
|
178
|
+
// Your test code here...
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Step 4:** Make sure your recorder app is running, then run tests
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
npx playwright test
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Advanced Configuration
|
|
190
|
+
|
|
191
|
+
You can customize the fixtures with different options:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// tests/example.spec.ts
|
|
195
|
+
import { createProboFixtures, expect } from "@probolabs/playwright/fixtures";
|
|
196
|
+
|
|
197
|
+
// Create custom fixtures with specific configuration
|
|
198
|
+
const test = createProboFixtures({
|
|
199
|
+
debugPort: 9333, // Default port where your recorder app runs
|
|
200
|
+
showBrowserConsole: true, // Show browser console logs
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test.describe("My Tests", () => {
|
|
204
|
+
test("custom configuration", async ({ page }) => {
|
|
205
|
+
// Your test code here...
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Requirements
|
|
211
|
+
|
|
212
|
+
- Your recorder app must be running with Chrome accessible via CDP
|
|
213
|
+
- Chrome must be launched with `--remote-debugging-port=9333` (or your custom port)
|
|
214
|
+
- The browser must have at least one page open (not just extension pages)
|
|
215
|
+
|
|
216
|
+
### Troubleshooting
|
|
217
|
+
|
|
218
|
+
**Error: "No browser context found"**
|
|
219
|
+
|
|
220
|
+
- Make sure your recorder app is running
|
|
221
|
+
- Check that Chrome is accessible at `http://localhost:9333`
|
|
222
|
+
- Verify the debug port matches your configuration
|
|
223
|
+
|
|
224
|
+
**Error: "No main page found"**
|
|
225
|
+
|
|
226
|
+
- Make sure your recorder app has opened a page
|
|
227
|
+
- The page should not be a chrome-extension:// URL
|
package/dist/fixtures.js
CHANGED
|
@@ -64,7 +64,12 @@ function createProboFixtures(config = {}) {
|
|
|
64
64
|
...extensionDirs.map(dir => `--load-extension=${dir}`),
|
|
65
65
|
'--disable-extensions-except=' + extensionDirs.join(','),
|
|
66
66
|
'--disable-web-security', // Allow extensions to work properly
|
|
67
|
-
'--disable-features=VizDisplayCompositor'
|
|
67
|
+
'--disable-features=VizDisplayCompositor',
|
|
68
|
+
// Anti-detection flags to match Chrome for Testing behavior
|
|
69
|
+
'--disable-blink-features=AutomationControlled',
|
|
70
|
+
'--disable-infobars',
|
|
71
|
+
'--no-first-run',
|
|
72
|
+
'--no-default-browser-check'
|
|
68
73
|
]
|
|
69
74
|
});
|
|
70
75
|
await use(context);
|
package/dist/fixtures.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.js","sources":["../src/fixtures.ts"],"sourcesContent":["import { test as base, chromium } from '@playwright/test';\
|
|
1
|
+
{"version":3,"file":"fixtures.js","sources":["../src/fixtures.ts"],"sourcesContent":["import { test as base, chromium } from '@playwright/test';\nimport { readFileSync, mkdtempSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { tmpdir } from 'os';\nimport AdmZip from 'adm-zip';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Configuration options for Probo fixtures\n */\nexport interface ProboFixturesConfig {\n /** Whether to show browser console logs */\n showBrowserConsole?: boolean;\n /** Custom path to extensions directory */\n extensionsPath?: string;\n}\n\n/**\n * Extracts a CRX file to a temporary directory\n * Uses adm-zip with manual ZIP content detection\n */\nfunction extractCrxFile(crxPath: string): string {\n const crxBuffer = readFileSync(crxPath);\n \n // Find ZIP content by looking for ZIP magic number (PK)\n let zipStart = -1;\n for (let i = 0; i < crxBuffer.length - 4; i++) {\n if (crxBuffer[i] === 0x50 && crxBuffer[i + 1] === 0x4B) { // \"PK\"\n zipStart = i;\n break;\n }\n }\n \n if (zipStart === -1) {\n throw new Error('Could not find ZIP content in CRX file');\n }\n \n const zipBuffer = crxBuffer.subarray(zipStart);\n \n // Create temporary directory\n const tempDir = mkdtempSync(join(tmpdir(), 'probo-extension-'));\n \n // Extract ZIP content\n const zip = new AdmZip(zipBuffer);\n zip.extractAllTo(tempDir, true);\n \n return tempDir;\n}\n\n/**\n * Creates Probo fixtures that launch Chromium with extensions\n * \n * @param config Configuration options for the fixtures\n * @returns Extended test function with Probo fixtures\n */\nexport function createProboFixtures(config: ProboFixturesConfig = {}) {\n const { showBrowserConsole = false, extensionsPath } = config;\n \n // Default extensions path\n const defaultExtensionsPath = join(__dirname, '../loaded_extensions');\n const extensionsDir = extensionsPath || defaultExtensionsPath;\n\n return base.extend({\n context: async ({headless}, use) => {\n // Extract extensions\n const extensionDirs: string[] = [];\n \n try {\n const crxFile = join(extensionsDir, 'microsoft-single-sign-on.crx');\n const extractedDir = extractCrxFile(crxFile);\n extensionDirs.push(extractedDir);\n } catch (error) {\n console.warn('Could not load Microsoft SSO extension:', error);\n }\n \n // Launch Chromium with extensions\n const userDataDir = mkdtempSync(join(tmpdir(), 'probo-user-data-'));\n \n const context = await chromium.launchPersistentContext(userDataDir, {\n headless, // Extensions work better in non-headless mode\n args: [\n ...extensionDirs.map(dir => `--load-extension=${dir}`),\n '--disable-extensions-except=' + extensionDirs.join(','),\n '--disable-web-security', // Allow extensions to work properly\n '--disable-features=VizDisplayCompositor',\n // Anti-detection flags to match Chrome for Testing behavior\n '--disable-blink-features=AutomationControlled',\n '--disable-infobars',\n '--no-first-run',\n '--no-default-browser-check'\n ]\n });\n \n await use(context);\n \n // Cleanup\n await context.close();\n },\n \n page: async ({ context }, use) => {\n const page = await context.newPage();\n \n // Set up console logging if requested\n if (showBrowserConsole) {\n page.on('console', msg => console.log('Browser console:', msg.text()));\n }\n \n await use(page);\n await page.close();\n },\n });\n}\n\n/**\n * Default Probo fixtures with standard configuration\n * Launches Chromium with Microsoft SSO extension\n */\nexport const test = createProboFixtures();\n\n/**\n * Re-export expect from Playwright for convenience\n */\nexport { expect } from '@playwright/test';\n"],"names":["base"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -98,9 +98,9 @@ interface RunStepParams extends Partial<PlaywrightTimeoutConfig> {
|
|
|
98
98
|
timeout?: number;
|
|
99
99
|
}
|
|
100
100
|
declare class ProboPlaywright {
|
|
101
|
-
private readonly
|
|
101
|
+
private readonly timeoutConfig;
|
|
102
102
|
private page;
|
|
103
|
-
constructor(
|
|
103
|
+
constructor(timeoutConfig?: Partial<PlaywrightTimeoutConfig>, page?: Page$1 | null);
|
|
104
104
|
/**
|
|
105
105
|
* Sets the Playwright page instance for this ProboPlaywright instance.
|
|
106
106
|
* Also applies the configured default navigation and action timeouts to the page.
|
|
@@ -140,6 +140,7 @@ declare class ProboPlaywright {
|
|
|
140
140
|
* @param value - The text value to fill into the input field
|
|
141
141
|
*/
|
|
142
142
|
private robustFill;
|
|
143
|
+
private robustTypeKeys;
|
|
143
144
|
/**
|
|
144
145
|
* Performs a robust click operation using multiple fallback strategies.
|
|
145
146
|
* Attempts standard click first, then mouse click at center coordinates, and finally native DOM events.
|
|
@@ -261,6 +262,12 @@ interface MailinatorMessage {
|
|
|
261
262
|
* OTP utility class for working with Mailinator API
|
|
262
263
|
*/
|
|
263
264
|
declare class OTP {
|
|
265
|
+
/**
|
|
266
|
+
* Flag to control whether messages should be deleted after OTP extraction
|
|
267
|
+
* Set to false for debugging purposes to keep messages in the inbox
|
|
268
|
+
* @default true
|
|
269
|
+
*/
|
|
270
|
+
static DELETE_MESSAGE_AFTER_OTP_EXTRACTION: boolean;
|
|
264
271
|
/**
|
|
265
272
|
* Fetches the last messages from Mailinator for a specific inbox
|
|
266
273
|
* @param inbox - The inbox name to check (without @domain)
|
|
@@ -274,6 +281,12 @@ declare class OTP {
|
|
|
274
281
|
* @returns Promise<MailinatorMessage> - The message details
|
|
275
282
|
*/
|
|
276
283
|
static fetchMessage(messageId: string): Promise<MailinatorMessage>;
|
|
284
|
+
/**
|
|
285
|
+
* Deletes a specific message by ID
|
|
286
|
+
* @param messageId - The message ID to delete
|
|
287
|
+
* @returns Promise<boolean> - True if deleted successfully, false otherwise
|
|
288
|
+
*/
|
|
289
|
+
static deleteMessage(messageId: string): Promise<boolean>;
|
|
277
290
|
/**
|
|
278
291
|
* Extracts OTP codes from message content
|
|
279
292
|
* @param message - The message to extract OTP from
|
|
@@ -296,13 +309,19 @@ declare class OTP {
|
|
|
296
309
|
static fetchAllInboxMessages(limit?: number, sort?: 'ascending' | 'descending', full?: boolean): Promise<MailinatorMessage[]>;
|
|
297
310
|
/**
|
|
298
311
|
* Waits for an OTP to arrive in the inbox and extracts it
|
|
299
|
-
* @param
|
|
300
|
-
* @param
|
|
301
|
-
* @param
|
|
302
|
-
* @param
|
|
312
|
+
* @param options - Configuration options for waiting for OTP
|
|
313
|
+
* @param options.inbox - The inbox name to monitor (optional - if not provided, searches all inboxes)
|
|
314
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 30000)
|
|
315
|
+
* @param options.checkInterval - How often to check in milliseconds (default: 1000)
|
|
316
|
+
* @param options.checkRecentMessagesSinceMs - When > 0, check messages from the last X milliseconds and return the most recent OTP (default: 0)
|
|
303
317
|
* @returns Promise<string | null> - The extracted OTP code or null if timeout/no OTP found
|
|
304
318
|
*/
|
|
305
|
-
static waitForOTP(
|
|
319
|
+
static waitForOTP(options?: {
|
|
320
|
+
inbox?: string;
|
|
321
|
+
timeout?: number;
|
|
322
|
+
checkInterval?: number;
|
|
323
|
+
checkRecentMessagesSinceMs?: number;
|
|
324
|
+
}): Promise<string | null>;
|
|
306
325
|
}
|
|
307
326
|
|
|
308
327
|
/**
|
|
@@ -320,10 +339,13 @@ interface ProboConfig {
|
|
|
320
339
|
timeoutConfig?: Partial<PlaywrightTimeoutConfig>;
|
|
321
340
|
}
|
|
322
341
|
interface RunStepOptions {
|
|
323
|
-
useCache: boolean;
|
|
324
|
-
stepIdFromServer?: number | null;
|
|
325
342
|
aiModel?: AIModel;
|
|
326
343
|
timeoutConfig?: PlaywrightTimeoutConfig;
|
|
344
|
+
stepId?: number;
|
|
345
|
+
}
|
|
346
|
+
interface AskAIOptions {
|
|
347
|
+
stepId?: number;
|
|
348
|
+
createStep?: boolean;
|
|
327
349
|
}
|
|
328
350
|
declare class Probo {
|
|
329
351
|
private highlighter;
|
|
@@ -333,10 +355,9 @@ declare class Probo {
|
|
|
333
355
|
private readonly aiModel;
|
|
334
356
|
private readonly timeoutConfig;
|
|
335
357
|
constructor({ scenarioName, token, apiUrl, enableConsoleLogs, logToConsole, logToFile, debugLevel, aiModel, timeoutConfig }: ProboConfig);
|
|
336
|
-
askAI(page: Page, question: string): Promise<any>;
|
|
337
|
-
runStep(page: Page, stepPrompt: string, argument?: string | boolean | null, options?: RunStepOptions): Promise<
|
|
358
|
+
askAI(page: Page, question: string, options: AskAIOptions): Promise<any>;
|
|
359
|
+
runStep(page: Page, stepPrompt: string, argument?: string | boolean | null, options?: RunStepOptions): Promise<string | void>;
|
|
338
360
|
private _handleCachedStep;
|
|
339
|
-
private _handleStepCreation;
|
|
340
361
|
private setupConsoleLogs;
|
|
341
362
|
getInitialPageState(page: Page): Promise<InitialPageState>;
|
|
342
363
|
findAndHighlightCandidateElements(page: Page, elementTags: string[]): Promise<FindCandidateInput>;
|
|
@@ -346,8 +367,8 @@ declare class Probo {
|
|
|
346
367
|
waitForMutationsToSettle(page: Page, timeout?: number, initTimeout?: number): Promise<boolean>;
|
|
347
368
|
screenshot(page: Page): Promise<string>;
|
|
348
369
|
private _handlePerformAction;
|
|
349
|
-
askAIHelper(page: Page, question: string): Promise<ServerResponse>;
|
|
370
|
+
askAIHelper(page: Page, question: string, options: AskAIOptions): Promise<ServerResponse>;
|
|
350
371
|
}
|
|
351
372
|
|
|
352
373
|
export { Highlighter, NavTracker, OTP, Probo, ProboPlaywright, findClosestVisibleElement };
|
|
353
|
-
export type { ElementTagType, MailinatorMessage, RunStepOptions };
|
|
374
|
+
export type { AskAIOptions, ElementTagType, MailinatorMessage, RunStepOptions };
|