automation_model 1.0.61 → 1.0.63
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/bin/auto_page.d.ts +1 -1
- package/bin/auto_page.js +27 -3
- package/bin/browser_manager.d.ts +3 -3
- package/bin/init_browser.js +3 -1
- package/bin/stable_browser.d.ts +11 -10
- package/bin/stable_browser.js +71 -31
- package/package.json +1 -1
package/bin/auto_page.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export function initContext(path: any, doNavigate?: boolean, headless?: boolean): Promise<any>;
|
|
1
|
+
export function initContext(path: any, doNavigate?: boolean, headless?: boolean, world?: null): Promise<any>;
|
|
2
2
|
export function navigate(path?: string): Promise<void>;
|
|
3
3
|
export function closeContext(): Promise<void>;
|
package/bin/auto_page.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { browserManager } from "./browser_manager.js";
|
|
2
2
|
import { getContext } from "./init_browser.js";
|
|
3
|
-
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
4
5
|
let context = null;
|
|
5
6
|
const navigate = async (path = "") => {
|
|
6
7
|
let url = null;
|
|
@@ -12,12 +13,35 @@ const navigate = async (path = "") => {
|
|
|
12
13
|
await context.stable.goto(url);
|
|
13
14
|
await context.stable.waitForPageLoad();
|
|
14
15
|
};
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const _findEmptyFolder = (folder) => {
|
|
17
|
+
if (!folder) {
|
|
18
|
+
folder = "./runs";
|
|
19
|
+
}
|
|
20
|
+
if (!fs.existsSync(folder)) {
|
|
21
|
+
fs.mkdirSync(folder);
|
|
22
|
+
}
|
|
23
|
+
let nextIndex = 1;
|
|
24
|
+
while (fs.existsSync(path.join(folder, nextIndex.toString()))) {
|
|
25
|
+
nextIndex++;
|
|
26
|
+
}
|
|
27
|
+
return path.join(folder, nextIndex.toString());
|
|
28
|
+
};
|
|
29
|
+
const initContext = async (path, doNavigate = true, headless = false, world = null) => {
|
|
17
30
|
if (context) {
|
|
18
31
|
return context;
|
|
19
32
|
}
|
|
20
33
|
context = await getContext(null, headless);
|
|
34
|
+
|
|
35
|
+
if (world) {
|
|
36
|
+
world.screenshot = true;
|
|
37
|
+
const reportFolder = _findEmptyFolder();
|
|
38
|
+
if (world.attach) {
|
|
39
|
+
world.attach(reportFolder, { mediaType: "text/plain" });
|
|
40
|
+
}
|
|
41
|
+
world.screenshotPath = reportFolder;
|
|
42
|
+
context.reportFolder = reportFolder;
|
|
43
|
+
}
|
|
44
|
+
|
|
21
45
|
if (doNavigate) {
|
|
22
46
|
await navigate(path);
|
|
23
47
|
}
|
package/bin/browser_manager.d.ts
CHANGED
|
@@ -7,9 +7,9 @@ declare class BrowserManager {
|
|
|
7
7
|
getBrowser(headless?: boolean): Promise<any>;
|
|
8
8
|
}
|
|
9
9
|
declare class Browser {
|
|
10
|
-
browser:
|
|
11
|
-
context:
|
|
12
|
-
page:
|
|
10
|
+
browser: any;
|
|
11
|
+
context: any;
|
|
12
|
+
page: any;
|
|
13
13
|
init(headless?: boolean): Promise<void>;
|
|
14
14
|
close(): Promise<void>;
|
|
15
15
|
}
|
package/bin/init_browser.js
CHANGED
|
@@ -17,6 +17,7 @@ const getContext = async function (environment = null, headless = false, logger
|
|
|
17
17
|
context.playContext = browser.context;
|
|
18
18
|
context.page = browser.page;
|
|
19
19
|
context.environment = environment;
|
|
20
|
+
|
|
20
21
|
context.stable = new StableBrowser(context.browser, context.page, logger);
|
|
21
22
|
await _initCookies(context);
|
|
22
23
|
return context;
|
|
@@ -48,7 +49,8 @@ const initEnvoronment = function () {
|
|
|
48
49
|
const envObject = JSON.parse(data);
|
|
49
50
|
//console.log("envObject", envObject);
|
|
50
51
|
Object.assign(environment, envObject);
|
|
51
|
-
console.log("env", environment);
|
|
52
|
+
//console.log("env", environment);
|
|
53
|
+
console.log("Base url: " + environment.baseUrl);
|
|
52
54
|
} catch (err) {
|
|
53
55
|
console.error("Error reading env.json", err);
|
|
54
56
|
}
|
package/bin/stable_browser.d.ts
CHANGED
|
@@ -9,24 +9,24 @@ export class StableBrowser {
|
|
|
9
9
|
_locateElementByText(scope: any, text1: any, tag1: any, regex?: boolean, _params?: null): Promise<any>;
|
|
10
10
|
_collectLocatorInformation(selectorHierarchy: any, index: number | undefined, scope: any, foundLocators: any, _params: any): Promise<void>;
|
|
11
11
|
_locate(selectors: any, info: any, _params: any, timeout?: number): Promise<any>;
|
|
12
|
-
click(selector: any, _params?: null, options?: {}): Promise<{
|
|
12
|
+
click(selector: any, _params?: null, options?: {}, world?: null): Promise<{
|
|
13
13
|
log: any[];
|
|
14
14
|
operation: string;
|
|
15
15
|
selector: any;
|
|
16
16
|
}>;
|
|
17
|
-
selectOption(selector: any, values: any, _params?: null, options?: {}): Promise<{
|
|
17
|
+
selectOption(selector: any, values: any, _params?: null, options?: {}, world?: null): Promise<{
|
|
18
18
|
log: any[];
|
|
19
19
|
operation: string;
|
|
20
20
|
selector: any;
|
|
21
21
|
}>;
|
|
22
|
-
fill(selector: any, value: any, enter?: boolean, _params?: null, options?: {}): Promise<{
|
|
22
|
+
fill(selector: any, value: any, enter?: boolean, _params?: null, options?: {}, world?: null): Promise<{
|
|
23
23
|
log: any[];
|
|
24
24
|
operation: string;
|
|
25
25
|
selector: any;
|
|
26
26
|
value: any;
|
|
27
27
|
}>;
|
|
28
|
-
getText(selector: any, _params?: null, options?: {}, info?: {}): Promise<any>;
|
|
29
|
-
containsPattern(selector: any, pattern: any, text: any, _params?: null, options?: {}): Promise<{
|
|
28
|
+
getText(selector: any, _params?: null, options?: {}, info?: {}, world?: null): Promise<any>;
|
|
29
|
+
containsPattern(selector: any, pattern: any, text: any, _params?: null, options?: {}, world?: null): Promise<{
|
|
30
30
|
log: any[];
|
|
31
31
|
operation: string;
|
|
32
32
|
selector: any;
|
|
@@ -34,20 +34,20 @@ export class StableBrowser {
|
|
|
34
34
|
pattern: any;
|
|
35
35
|
foundText: any;
|
|
36
36
|
}>;
|
|
37
|
-
containsText(selector: any, text: any, _params?: null, options?: {}): Promise<{
|
|
37
|
+
containsText(selector: any, text: any, _params?: null, options?: {}, world?: null): Promise<{
|
|
38
38
|
log: any[];
|
|
39
39
|
operation: string;
|
|
40
40
|
selector: any;
|
|
41
41
|
value: any;
|
|
42
42
|
foundText: any;
|
|
43
43
|
}>;
|
|
44
|
-
_screenShot(options?: {}): Promise<void>;
|
|
45
|
-
verifyElementExistInPage(selector: any, _params?: null, options?: {}): Promise<{
|
|
44
|
+
_screenShot(options?: {}, world?: null): Promise<void>;
|
|
45
|
+
verifyElementExistInPage(selector: any, _params?: null, options?: {}, world?: null): Promise<{
|
|
46
46
|
log: any[];
|
|
47
47
|
operation: string;
|
|
48
48
|
selector: any;
|
|
49
49
|
}>;
|
|
50
|
-
analyzeTable(selector: any, query: any, operator: any, value: any, _params?: null, options?: {}): Promise<{
|
|
50
|
+
analyzeTable(selector: any, query: any, operator: any, value: any, _params?: null, options?: {}, world?: null): Promise<{
|
|
51
51
|
log: any[];
|
|
52
52
|
operation: string;
|
|
53
53
|
selector: any;
|
|
@@ -56,5 +56,6 @@ export class StableBrowser {
|
|
|
56
56
|
operator: any;
|
|
57
57
|
value: any;
|
|
58
58
|
}>;
|
|
59
|
-
waitForPageLoad(options?: {}): Promise<void>;
|
|
59
|
+
waitForPageLoad(options?: {}, world?: null): Promise<void>;
|
|
60
|
+
_reportToWorld(world: any, properties?: {}): void;
|
|
60
61
|
}
|
package/bin/stable_browser.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import reg_parser from "regex-parser";
|
|
2
2
|
import { expect } from "@playwright/test";
|
|
3
3
|
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
4
5
|
import { getTableCells } from "./table_analyze.js";
|
|
5
6
|
let configuration = null;
|
|
6
7
|
class StableBrowser {
|
|
@@ -186,71 +187,75 @@ class StableBrowser {
|
|
|
186
187
|
throw new Error("failed to locate first element no elements found, " + JSON.stringify(info));
|
|
187
188
|
}
|
|
188
189
|
|
|
189
|
-
async click(selector, _params = null, options = {}) {
|
|
190
|
+
async click(selector, _params = null, options = {}, world = null) {
|
|
190
191
|
const info = {};
|
|
191
192
|
info.log = [];
|
|
192
193
|
info.operation = "click";
|
|
193
194
|
info.selector = selector;
|
|
194
|
-
|
|
195
|
+
this._reportToWorld(world, { command: "click", params: _params, selector: selector });
|
|
195
196
|
try {
|
|
196
197
|
let element = await this._locate(selector, info, _params);
|
|
197
198
|
|
|
198
|
-
await this._screenShot(options);
|
|
199
|
+
await this._screenShot(options, world);
|
|
199
200
|
try {
|
|
200
201
|
await element.click({ timeout: 5000 });
|
|
201
202
|
} catch (e) {
|
|
202
203
|
info.log.push("click failed, will try force click");
|
|
204
|
+
this._reportToWorld(world, { message: "click failed, will try force click" });
|
|
203
205
|
await element.click({ timeout: 10000, force: true });
|
|
204
206
|
}
|
|
207
|
+
this._reportToWorld(world, { result: "success", info: info });
|
|
205
208
|
await this.waitForPageLoad();
|
|
206
209
|
return info;
|
|
207
210
|
} catch (e) {
|
|
208
211
|
this.logger.error("click failed " + JSON.stringify(info));
|
|
212
|
+
this._reportToWorld(world, { result: "failed", info: info, error: e });
|
|
209
213
|
Object.assign(e, { info: info });
|
|
210
|
-
await this._screenShot(options);
|
|
214
|
+
await this._screenShot(options, world);
|
|
211
215
|
throw e;
|
|
212
|
-
|
|
213
|
-
this.logger.info("click failed, will try next selector");
|
|
214
216
|
}
|
|
215
217
|
}
|
|
216
218
|
|
|
217
|
-
async selectOption(selector, values, _params = null, options = {}) {
|
|
219
|
+
async selectOption(selector, values, _params = null, options = {}, world = null) {
|
|
218
220
|
const info = {};
|
|
219
221
|
info.log = [];
|
|
220
222
|
info.operation = "selectOptions";
|
|
221
223
|
info.selector = selector;
|
|
222
|
-
|
|
224
|
+
this._reportToWorld(world, { command: "select", values, params: _params, selector: selector });
|
|
223
225
|
try {
|
|
224
226
|
let element = await this._locate(selector, info, _params);
|
|
225
227
|
|
|
226
|
-
await this._screenShot(options);
|
|
228
|
+
await this._screenShot(options, world);
|
|
227
229
|
try {
|
|
228
230
|
await element.selectOption(values, { timeout: 5000 });
|
|
229
231
|
} catch (e) {
|
|
230
232
|
info.log.push("selectOption failed, will try force");
|
|
233
|
+
this._reportToWorld(world, { message: "select failed, will try force select" });
|
|
231
234
|
await element.selectOption(values, { timeout: 10000, force: true });
|
|
232
235
|
}
|
|
233
236
|
await this.waitForPageLoad();
|
|
234
237
|
return info;
|
|
235
238
|
} catch (e) {
|
|
236
239
|
this.logger.error("selectOption failed " + JSON.stringify(info));
|
|
240
|
+
this._reportToWorld(world, { result: "failed", info: info, error: e });
|
|
237
241
|
Object.assign(e, { info: info });
|
|
238
|
-
await this._screenShot(options);
|
|
242
|
+
await this._screenShot(options, world);
|
|
239
243
|
throw e;
|
|
240
244
|
|
|
241
245
|
this.logger.info("click failed, will try next selector");
|
|
242
246
|
}
|
|
243
247
|
}
|
|
244
248
|
|
|
245
|
-
async fill(selector, value, enter = false, _params = null, options = {}) {
|
|
249
|
+
async fill(selector, value, enter = false, _params = null, options = {}, world = null) {
|
|
246
250
|
const info = {};
|
|
247
251
|
info.log = [];
|
|
248
252
|
info.operation = "fill";
|
|
249
253
|
info.selector = selector;
|
|
250
254
|
info.value = value;
|
|
255
|
+
this._reportToWorld(world, { command: "fill", value, enter, params: _params, selector: selector });
|
|
251
256
|
try {
|
|
252
257
|
let element = await this._locate(selector, info, _params);
|
|
253
|
-
await this._screenShot(options);
|
|
258
|
+
await this._screenShot(options, world);
|
|
254
259
|
await element.fill(value, { timeout: 10000 });
|
|
255
260
|
await element.dispatchEvent("change");
|
|
256
261
|
if (enter) {
|
|
@@ -260,18 +265,19 @@ class StableBrowser {
|
|
|
260
265
|
return info;
|
|
261
266
|
} catch (e) {
|
|
262
267
|
this.logger.error("fill failed " + JSON.stringify(info));
|
|
268
|
+
this._reportToWorld(world, { result: "failed", info: info, error: e });
|
|
263
269
|
Object.assign(e, { info: info });
|
|
264
|
-
await this._screenShot(options);
|
|
270
|
+
await this._screenShot(options, world);
|
|
265
271
|
throw e;
|
|
266
272
|
}
|
|
267
273
|
}
|
|
268
274
|
|
|
269
|
-
async getText(selector, _params = null, options = {}, info = {}) {
|
|
275
|
+
async getText(selector, _params = null, options = {}, info = {}, world = null) {
|
|
270
276
|
if (!info.log) {
|
|
271
277
|
info.log = [];
|
|
272
278
|
}
|
|
273
279
|
let element = await this._locate(selector, info, _params);
|
|
274
|
-
await this._screenShot(options);
|
|
280
|
+
await this._screenShot(options, world);
|
|
275
281
|
try {
|
|
276
282
|
return await element.innerText();
|
|
277
283
|
} catch (e) {
|
|
@@ -279,7 +285,7 @@ class StableBrowser {
|
|
|
279
285
|
return await element.textContent();
|
|
280
286
|
}
|
|
281
287
|
}
|
|
282
|
-
async containsPattern(selector, pattern, text, _params = null, options = {}) {
|
|
288
|
+
async containsPattern(selector, pattern, text, _params = null, options = {}, world = null) {
|
|
283
289
|
const info = {};
|
|
284
290
|
info.log = [];
|
|
285
291
|
info.operation = "containsPattern";
|
|
@@ -287,8 +293,9 @@ class StableBrowser {
|
|
|
287
293
|
info.value = text;
|
|
288
294
|
info.pattern = pattern;
|
|
289
295
|
let foundText = null;
|
|
296
|
+
this._reportToWorld(world, { command: "contains", pattern, text, params: _params, selector: selector });
|
|
290
297
|
try {
|
|
291
|
-
foundText = await this.getText(selector, _params, options, info);
|
|
298
|
+
foundText = await this.getText(selector, _params, options, info, world);
|
|
292
299
|
let escapedText = text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
293
300
|
pattern = pattern.replace("{text}", escapedText);
|
|
294
301
|
let regex = new RegExp(pattern, "m");
|
|
@@ -300,20 +307,21 @@ class StableBrowser {
|
|
|
300
307
|
} catch (e) {
|
|
301
308
|
this.logger.error("verify element contains text failed " + JSON.stringify(info));
|
|
302
309
|
this.logger.error("found text " + foundText + " pattern " + pattern);
|
|
310
|
+
this._reportToWorld(world, { result: "failed", info: info, error: e });
|
|
303
311
|
Object.assign(e, { info: info });
|
|
304
|
-
await this._screenShot(options);
|
|
312
|
+
await this._screenShot(options, world);
|
|
305
313
|
throw e;
|
|
306
314
|
}
|
|
307
315
|
}
|
|
308
316
|
|
|
309
|
-
async containsText(selector, text, _params = null, options = {}) {
|
|
317
|
+
async containsText(selector, text, _params = null, options = {}, world = null) {
|
|
310
318
|
const info = {};
|
|
311
319
|
info.log = [];
|
|
312
320
|
info.operation = "containsText";
|
|
313
321
|
info.selector = selector;
|
|
314
322
|
info.value = text;
|
|
315
323
|
try {
|
|
316
|
-
let foundText = await this.getText(selector, _params, options, info);
|
|
324
|
+
let foundText = await this.getText(selector, _params, options, info, world);
|
|
317
325
|
if (!foundText.includes(text)) {
|
|
318
326
|
info.foundText = foundText;
|
|
319
327
|
throw new Error("element doesn't contain text " + text);
|
|
@@ -321,35 +329,51 @@ class StableBrowser {
|
|
|
321
329
|
return info;
|
|
322
330
|
} catch (e) {
|
|
323
331
|
this.logger.error("verify element contains text failed " + JSON.stringify(info));
|
|
332
|
+
this._reportToWorld(world, { result: "failed", info: info, error: e });
|
|
324
333
|
Object.assign(e, { info: info });
|
|
325
|
-
await this._screenShot(options);
|
|
334
|
+
await this._screenShot(options, world);
|
|
326
335
|
throw e;
|
|
327
336
|
}
|
|
328
337
|
}
|
|
329
|
-
async _screenShot(options = {}) {
|
|
330
|
-
if (
|
|
338
|
+
async _screenShot(options = {}, world = null) {
|
|
339
|
+
if (world && world.attach && world.screenshot && world.screenshotPath) {
|
|
340
|
+
if (!fs.existsSync(world.screenshotPath)) {
|
|
341
|
+
fs.mkdirSync(world.screenshotPath, { recursive: true });
|
|
342
|
+
}
|
|
343
|
+
let nextIndex = 1;
|
|
344
|
+
while (fs.existsSync(path.join(world.screenshotPath, nextIndex + ".png"))) {
|
|
345
|
+
nextIndex++;
|
|
346
|
+
}
|
|
347
|
+
const screenshotPath = path.join(world.screenshotPath, nextIndex + ".png");
|
|
348
|
+
await this.page.screenshot({ path: screenshotPath });
|
|
349
|
+
await world.attach(JSON.stringify({ path: screenshotPath }), {
|
|
350
|
+
mediaType: "application/json",
|
|
351
|
+
});
|
|
352
|
+
} else if (options.screenshot) {
|
|
331
353
|
await this.page.screenshot({ path: options.screenshotPath });
|
|
332
354
|
}
|
|
333
355
|
}
|
|
334
|
-
async verifyElementExistInPage(selector, _params = null, options = {}) {
|
|
356
|
+
async verifyElementExistInPage(selector, _params = null, options = {}, world = null) {
|
|
335
357
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
336
358
|
const info = {};
|
|
337
359
|
info.log = [];
|
|
338
360
|
info.operation = "verify";
|
|
339
361
|
info.selector = selector;
|
|
362
|
+
this._reportToWorld(world, { command: "verify", params: _params, selector: selector });
|
|
340
363
|
try {
|
|
341
364
|
const element = await this._locate(selector, info, _params);
|
|
342
|
-
await this._screenShot(options);
|
|
365
|
+
await this._screenShot(options, world);
|
|
343
366
|
await expect(element).toHaveCount(1, { timeout: 10000 });
|
|
344
367
|
return info;
|
|
345
368
|
} catch (e) {
|
|
346
369
|
this.logger.error("verify failed " + JSON.stringify(info));
|
|
370
|
+
this._reportToWorld(world, { result: "failed", info: info, error: e });
|
|
347
371
|
Object.assign(e, { info: info });
|
|
348
|
-
await this._screenShot(options);
|
|
372
|
+
await this._screenShot(options, world);
|
|
349
373
|
throw e;
|
|
350
374
|
}
|
|
351
375
|
}
|
|
352
|
-
async analyzeTable(selector, query, operator, value, _params = null, options = {}) {
|
|
376
|
+
async analyzeTable(selector, query, operator, value, _params = null, options = {}, world = null) {
|
|
353
377
|
const info = {};
|
|
354
378
|
info.log = [];
|
|
355
379
|
info.operation = "analyzeTable";
|
|
@@ -359,9 +383,17 @@ class StableBrowser {
|
|
|
359
383
|
info.query_fixed = query;
|
|
360
384
|
info.operator = operator;
|
|
361
385
|
info.value = value;
|
|
386
|
+
this._reportToWorld(world, {
|
|
387
|
+
command: "analyzeTable",
|
|
388
|
+
query,
|
|
389
|
+
operator,
|
|
390
|
+
value,
|
|
391
|
+
params: _params,
|
|
392
|
+
selector: selector,
|
|
393
|
+
});
|
|
362
394
|
try {
|
|
363
395
|
let table = await this._locate(selector, info, _params);
|
|
364
|
-
await this._screenShot(options);
|
|
396
|
+
await this._screenShot(options, world);
|
|
365
397
|
const cells = await getTableCells(this.page, table, query, info);
|
|
366
398
|
|
|
367
399
|
if (cells.error) {
|
|
@@ -436,13 +468,15 @@ class StableBrowser {
|
|
|
436
468
|
return info;
|
|
437
469
|
} catch (e) {
|
|
438
470
|
this.logger.error("analyzeTable failed " + JSON.stringify(info));
|
|
471
|
+
this._reportToWorld(world, { result: "failed", info: info, error: e });
|
|
439
472
|
Object.assign(e, { info: info });
|
|
440
|
-
await this._screenShot(options);
|
|
473
|
+
await this._screenShot(options, world);
|
|
441
474
|
throw e;
|
|
442
475
|
}
|
|
443
476
|
}
|
|
444
|
-
async waitForPageLoad(options = {}) {
|
|
477
|
+
async waitForPageLoad(options = {}, world = null) {
|
|
445
478
|
let timeout = 10000;
|
|
479
|
+
this._reportToWorld(world, { command: "waitForPageLoade" });
|
|
446
480
|
if (!configuration) {
|
|
447
481
|
try {
|
|
448
482
|
if (fs.existsSync("ai_config.json")) {
|
|
@@ -473,7 +507,13 @@ class StableBrowser {
|
|
|
473
507
|
console.log("waitForPageLoad error, ignored");
|
|
474
508
|
}
|
|
475
509
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
476
|
-
await this._screenShot(options);
|
|
510
|
+
await this._screenShot(options, world);
|
|
511
|
+
}
|
|
512
|
+
_reportToWorld(world, properties = {}) {
|
|
513
|
+
if (!world || !world.attach) {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
world.attach(JSON.stringify(properties), { mediaType: "application/json" });
|
|
477
517
|
}
|
|
478
518
|
}
|
|
479
519
|
|