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.
@@ -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
- const initContext = async (path, doNavigate = true, headless = false) => {
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
  }
@@ -7,9 +7,9 @@ declare class BrowserManager {
7
7
  getBrowser(headless?: boolean): Promise<any>;
8
8
  }
9
9
  declare class Browser {
10
- browser: import("playwright-core").Browser | null;
11
- context: import("playwright-core").BrowserContext | null;
12
- page: import("playwright-core").Page | null;
10
+ browser: any;
11
+ context: any;
12
+ page: any;
13
13
  init(headless?: boolean): Promise<void>;
14
14
  close(): Promise<void>;
15
15
  }
@@ -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
  }
@@ -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
  }
@@ -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 (options.screenshot) {
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "automation_model",
3
- "version": "1.0.61",
3
+ "version": "1.0.63",
4
4
  "description": "An automation infrastructure module to be use for generative AI automation projects.",
5
5
  "main": "bin/index.js",
6
6
  "type": "module",