automation_model 1.0.448-dev → 1.0.448

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.
Files changed (74) hide show
  1. package/README.md +133 -0
  2. package/lib/analyze_helper.js.map +1 -1
  3. package/lib/api.d.ts +43 -2
  4. package/lib/api.js +239 -49
  5. package/lib/api.js.map +1 -1
  6. package/lib/auto_page.d.ts +7 -2
  7. package/lib/auto_page.js +232 -49
  8. package/lib/auto_page.js.map +1 -1
  9. package/lib/browser_manager.d.ts +7 -3
  10. package/lib/browser_manager.js +172 -48
  11. package/lib/browser_manager.js.map +1 -1
  12. package/lib/bruno.d.ts +2 -0
  13. package/lib/bruno.js +381 -0
  14. package/lib/bruno.js.map +1 -0
  15. package/lib/command_common.d.ts +6 -0
  16. package/lib/command_common.js +202 -0
  17. package/lib/command_common.js.map +1 -0
  18. package/lib/date_time.js.map +1 -1
  19. package/lib/drawRect.js.map +1 -1
  20. package/lib/environment.d.ts +1 -0
  21. package/lib/environment.js +6 -3
  22. package/lib/environment.js.map +1 -1
  23. package/lib/error-messages.d.ts +6 -0
  24. package/lib/error-messages.js +206 -0
  25. package/lib/error-messages.js.map +1 -0
  26. package/lib/file_checker.d.ts +1 -0
  27. package/lib/file_checker.js +61 -0
  28. package/lib/file_checker.js.map +1 -0
  29. package/lib/find_function.js.map +1 -1
  30. package/lib/generation_scripts.d.ts +4 -0
  31. package/lib/generation_scripts.js +2 -0
  32. package/lib/generation_scripts.js.map +1 -0
  33. package/lib/index.d.ts +3 -0
  34. package/lib/index.js +3 -0
  35. package/lib/index.js.map +1 -1
  36. package/lib/init_browser.d.ts +4 -2
  37. package/lib/init_browser.js +118 -12
  38. package/lib/init_browser.js.map +1 -1
  39. package/lib/locate_element.d.ts +7 -0
  40. package/lib/locate_element.js +215 -0
  41. package/lib/locate_element.js.map +1 -0
  42. package/lib/locator.d.ts +37 -0
  43. package/lib/locator.js +172 -0
  44. package/lib/locator.js.map +1 -1
  45. package/lib/locator_log.d.ts +26 -0
  46. package/lib/locator_log.js +69 -0
  47. package/lib/locator_log.js.map +1 -0
  48. package/lib/network.d.ts +3 -0
  49. package/lib/network.js +183 -0
  50. package/lib/network.js.map +1 -0
  51. package/lib/route.d.ts +33 -0
  52. package/lib/route.js +325 -0
  53. package/lib/route.js.map +1 -0
  54. package/lib/scripts/axe.mini.js +12 -0
  55. package/lib/snapshot_validation.d.ts +37 -0
  56. package/lib/snapshot_validation.js +357 -0
  57. package/lib/snapshot_validation.js.map +1 -0
  58. package/lib/stable_browser.d.ts +152 -56
  59. package/lib/stable_browser.js +2568 -1323
  60. package/lib/stable_browser.js.map +1 -1
  61. package/lib/table.d.ts +15 -0
  62. package/lib/table.js +257 -0
  63. package/lib/table.js.map +1 -0
  64. package/lib/table_analyze.js.map +1 -1
  65. package/lib/table_helper.d.ts +19 -0
  66. package/lib/table_helper.js +116 -0
  67. package/lib/table_helper.js.map +1 -0
  68. package/lib/test_context.d.ts +7 -0
  69. package/lib/test_context.js +15 -10
  70. package/lib/test_context.js.map +1 -1
  71. package/lib/utils.d.ts +35 -2
  72. package/lib/utils.js +683 -11
  73. package/lib/utils.js.map +1 -1
  74. package/package.json +21 -11
package/lib/network.js ADDED
@@ -0,0 +1,183 @@
1
+ import path from "path";
2
+ import fs from "fs";
3
+ function _getNetworkFile(world = null, web = null, context = null) {
4
+ let networkFile = null;
5
+ if (world && world.reportFolder) {
6
+ networkFile = path.join(world.reportFolder, "network.json");
7
+ }
8
+ else if (web.reportFolder) {
9
+ networkFile = path.join(web.reportFolder, "network.json");
10
+ }
11
+ else if (context && context.reportFolder) {
12
+ networkFile = path.join(context.reportFolder, "network.json");
13
+ }
14
+ else {
15
+ networkFile = "network.json";
16
+ }
17
+ return networkFile;
18
+ }
19
+ function registerDownloadEvent(page, world, context) {
20
+ if (page) {
21
+ let downloadPath = "./downloads";
22
+ if (world && world.downloadsPath) {
23
+ downloadPath = world.downloadsPath;
24
+ }
25
+ else if (context && context.downloadsPath) {
26
+ downloadPath = context.downloadsPath;
27
+ }
28
+ if (!fs.existsSync(downloadPath)) {
29
+ try {
30
+ fs.mkdirSync(downloadPath);
31
+ }
32
+ catch (e) {
33
+ // ignore
34
+ }
35
+ }
36
+ page.on("download", async (download) => {
37
+ const suggestedFilename = download.suggestedFilename(); // Get the original file name
38
+ const filePath = `${downloadPath}/${suggestedFilename}`;
39
+ // Save the download with the original name
40
+ await download.saveAs(filePath);
41
+ console.log(`Downloaded file saved as: ${filePath}`);
42
+ });
43
+ }
44
+ }
45
+ function registerNetworkEvents(world, web, context, page) {
46
+ const networkFile = _getNetworkFile(world, web, context);
47
+ function saveNetworkData() {
48
+ if (context && context.networkData) {
49
+ fs.writeFileSync(networkFile, JSON.stringify(context.networkData, null, 2), "utf8");
50
+ }
51
+ }
52
+ if (!context) {
53
+ console.error("No context found to register network events");
54
+ return;
55
+ }
56
+ // Map to hold request start times and IDs
57
+ const requestTimes = new Map();
58
+ let requestIdCounter = 0;
59
+ if (page) {
60
+ if (!context.networkData) {
61
+ context.networkData = [];
62
+ const networkData = context.networkData;
63
+ // Event listener for when a request is made
64
+ page.on("request", (request) => {
65
+ const requestId = requestIdCounter++;
66
+ request.requestId = requestId; // Assign a unique ID to the request
67
+ const startTime = Date.now();
68
+ requestTimes.set(requestId, startTime);
69
+ // Initialize data for this request
70
+ networkData.push({
71
+ requestId,
72
+ requestStart: startTime,
73
+ requestUrl: request.url(),
74
+ method: request.method(),
75
+ status: "Pending",
76
+ responseTime: null,
77
+ responseReceived: null,
78
+ responseEnd: null,
79
+ size: null,
80
+ });
81
+ saveNetworkData();
82
+ });
83
+ // Event listener for when a response is received
84
+ page.on("response", async (response) => {
85
+ const request = response.request();
86
+ const requestId = request.requestId;
87
+ const receivedTime = Date.now();
88
+ // Find the corresponding data object
89
+ const data = networkData.find((item) => item.requestId === requestId);
90
+ if (data) {
91
+ data.status = response.status();
92
+ data.responseReceived = receivedTime;
93
+ saveNetworkData();
94
+ }
95
+ else {
96
+ console.error("No data found for request ID", requestId);
97
+ }
98
+ });
99
+ // Event listener for when a request is finished
100
+ page.on("requestfinished", async (request) => {
101
+ const requestId = request.requestId;
102
+ const endTime = Date.now();
103
+ const startTime = requestTimes.get(requestId);
104
+ const response = await request.response();
105
+ const timing = request.timing();
106
+ // Find the corresponding data object
107
+ const data = networkData.find((item) => item.requestId === requestId);
108
+ if (data) {
109
+ data.responseEnd = endTime;
110
+ data.responseTime = endTime - startTime;
111
+ // Get response size
112
+ try {
113
+ const body = await response.body();
114
+ data.size = body.length;
115
+ }
116
+ catch (e) {
117
+ data.size = 0;
118
+ }
119
+ const type = request.resourceType();
120
+ /*
121
+ domainLookupStart: 80.655,
122
+ domainLookupEnd: 80.668,
123
+ connectStart: 80.668,
124
+ secureConnectionStart: 106.688,
125
+ connectEnd: 129.69,
126
+ requestStart: 129.81,
127
+ responseStart: 187.006,
128
+ responseEnd: 188.209
129
+ */
130
+ data.type = type;
131
+ data.domainLookupStart = timing.domainLookupStart;
132
+ data.domainLookupEnd = timing.domainLookupEnd;
133
+ data.connectStart = timing.connectStart;
134
+ data.secureConnectionStart = timing.secureConnectionStart;
135
+ data.connectEnd = timing.connectEnd;
136
+ data.requestStart = timing.requestStart;
137
+ data.responseStart = timing.responseStart;
138
+ data.responseEnd = timing.responseEnd;
139
+ saveNetworkData();
140
+ if (world && world.attach) {
141
+ world.attach(JSON.stringify(data), { mediaType: "application/json+network" });
142
+ }
143
+ }
144
+ else {
145
+ console.error("No data found for request ID", requestId);
146
+ }
147
+ });
148
+ // Event listener for when a request fails
149
+ page.on("requestfailed", async (request) => {
150
+ const requestId = request.requestId;
151
+ const endTime = Date.now();
152
+ const startTime = requestTimes.get(requestId);
153
+ try {
154
+ const res = await request.response();
155
+ const statusCode = res ? res.status() : request.failure().errorText;
156
+ // Find the corresponding data object
157
+ const data = networkData.find((item) => item.requestId === requestId);
158
+ if (data) {
159
+ data.responseEnd = endTime;
160
+ data.responseTime = endTime - startTime;
161
+ data.status = statusCode;
162
+ data.size = 0;
163
+ saveNetworkData();
164
+ if (world && world.attach) {
165
+ world.attach(JSON.stringify(data), { mediaType: "application/json+network" });
166
+ }
167
+ }
168
+ else {
169
+ console.error("No data found for request ID", requestId);
170
+ }
171
+ }
172
+ catch (error) {
173
+ // ignore
174
+ }
175
+ });
176
+ }
177
+ }
178
+ else {
179
+ console.error("No page found to register network events");
180
+ }
181
+ }
182
+ export { registerNetworkEvents, registerDownloadEvent };
183
+ //# sourceMappingURL=network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/network.ts"],"names":[],"mappings":"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"}
package/lib/route.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ export interface Route {
2
+ template: string;
3
+ routes: RouteItem[];
4
+ }
5
+ export interface RouteItem {
6
+ filters: {
7
+ path: string;
8
+ queryParams: Record<string, string> | null;
9
+ method: string | null;
10
+ };
11
+ actions: Action[];
12
+ mandatory: boolean;
13
+ timeout: number;
14
+ }
15
+ export interface Action {
16
+ type: string;
17
+ config: any;
18
+ }
19
+ export declare function registerBeforeStepRoutes(context: any, stepName: string): Promise<void>;
20
+ export declare function registerAfterStepRoutes(context: any): Promise<{
21
+ url: string;
22
+ filters: {
23
+ path: string;
24
+ queryParams: Record<string, string> | null;
25
+ method: string | null;
26
+ };
27
+ actions: {
28
+ type: string;
29
+ description: string;
30
+ status: "timeout" | "success" | "fail";
31
+ }[];
32
+ overallStatus: "timeout" | "success" | "fail";
33
+ }[]>;
package/lib/route.js ADDED
@@ -0,0 +1,325 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import objectPath from "object-path";
4
+ let loadedRoutes = null;
5
+ async function loadRoutes() {
6
+ if (loadedRoutes !== null)
7
+ return loadedRoutes;
8
+ try {
9
+ const dir = path.join(process.cwd(), "data", "routes");
10
+ if (!(await folderExists(dir))) {
11
+ loadedRoutes = [];
12
+ return loadedRoutes;
13
+ }
14
+ const files = await fs.readdir(dir);
15
+ const jsonFiles = files.filter((f) => f.endsWith(".json"));
16
+ const allRoutes = [];
17
+ for (const file of jsonFiles) {
18
+ const content = await fs.readFile(path.join(dir, file), "utf-8");
19
+ const routeObj = JSON.parse(content);
20
+ allRoutes.push(routeObj);
21
+ }
22
+ loadedRoutes = allRoutes;
23
+ }
24
+ catch (error) {
25
+ console.error("Error loading routes:", error);
26
+ loadedRoutes = [];
27
+ }
28
+ return loadedRoutes;
29
+ }
30
+ function matchRoute(routeItem, req) {
31
+ const url = new URL(req.request().url());
32
+ const methodMatch = !routeItem.filters.method || routeItem.filters.method === req.request().method();
33
+ const pathMatch = routeItem.filters.path === url.pathname;
34
+ const queryParams = routeItem.filters.queryParams;
35
+ const queryMatch = !queryParams || Object.entries(queryParams).every(([key, value]) => url.searchParams.get(key) === value);
36
+ return methodMatch && pathMatch && queryMatch;
37
+ }
38
+ let debug = false;
39
+ export async function registerBeforeStepRoutes(context, stepName) {
40
+ const page = context.web.page;
41
+ if (!page)
42
+ throw new Error("context.web.page is missing");
43
+ const stepTemplate = _stepNameToTemplate(stepName);
44
+ const routes = await loadRoutes();
45
+ const matchedRouteDefs = routes.filter((r) => r.template === stepTemplate);
46
+ const allRouteItems = matchedRouteDefs.flatMap((r) => r.routes);
47
+ if (!context.__routeState) {
48
+ context.__routeState = { matched: [] };
49
+ }
50
+ // Pre-register all mandatory routes
51
+ for (const item of allRouteItems) {
52
+ if (item.mandatory) {
53
+ const tracking = {
54
+ routeItem: item,
55
+ url: "",
56
+ completed: false,
57
+ startedAt: Date.now(),
58
+ actionResults: [],
59
+ };
60
+ tracking.timer = setTimeout(() => {
61
+ if (!tracking.completed) {
62
+ console.error(`[MANDATORY] Request to ${item.filters.path} did not complete within ${item.timeout}ms`);
63
+ }
64
+ }, item.timeout);
65
+ context.__routeState.matched.push(tracking);
66
+ }
67
+ }
68
+ page.route("**/*", async (route) => {
69
+ const request = route.request();
70
+ // print the url if debug is enabled
71
+ if (debug) {
72
+ console.log(`Intercepting request: ${request.method()} ${request.url()}`);
73
+ }
74
+ const matchedItem = allRouteItems.find((item) => matchRoute(item, route));
75
+ if (!matchedItem)
76
+ return route.continue();
77
+ if (debug) {
78
+ console.log(`Matched route item: ${JSON.stringify(matchedItem)}`);
79
+ }
80
+ // Find pre-registered tracker
81
+ let tracking = context.__routeState.matched.find((t) => t.routeItem === matchedItem && !t.completed);
82
+ // If not mandatory, register dynamically
83
+ if (!tracking) {
84
+ tracking = {
85
+ routeItem: matchedItem,
86
+ url: request.url(),
87
+ completed: false,
88
+ startedAt: Date.now(),
89
+ actionResults: [],
90
+ };
91
+ context.__routeState.matched.push(tracking);
92
+ }
93
+ else {
94
+ tracking.url = request.url();
95
+ }
96
+ let response;
97
+ try {
98
+ response = await route.fetch();
99
+ }
100
+ catch (e) {
101
+ console.error("Fetch failed for", request.url(), e);
102
+ if (tracking?.timer)
103
+ clearTimeout(tracking.timer);
104
+ return route.abort();
105
+ }
106
+ let status = response.status();
107
+ let body = await response.text();
108
+ let headers = response.headers();
109
+ let json;
110
+ try {
111
+ json = JSON.parse(body);
112
+ }
113
+ catch (_) { }
114
+ const actionResults = [];
115
+ for (const action of matchedItem.actions) {
116
+ let actionStatus = "success";
117
+ const description = JSON.stringify(action.config);
118
+ switch (action.type) {
119
+ case "status_code_verification":
120
+ if (status !== action.config) {
121
+ console.error(`[status_code_verification] Expected ${action.config}, got ${status}`);
122
+ actionStatus = "fail";
123
+ }
124
+ else {
125
+ console.log(`[status_code_verification] Passed`);
126
+ }
127
+ break;
128
+ case "json_modify":
129
+ if (!json) {
130
+ console.error(`[json_modify] Response is not JSON`);
131
+ actionStatus = "fail";
132
+ }
133
+ else {
134
+ for (const mod of action.config) {
135
+ objectPath.set(json, mod.path, mod.value);
136
+ console.log(`[json_modify] Modified path ${mod.path} to ${mod.value}`);
137
+ }
138
+ console.log(`[json_modify] Modified JSON`);
139
+ }
140
+ break;
141
+ case "status_code_change":
142
+ status = action.config;
143
+ console.log(`[status_code_change] Status changed to ${status}`);
144
+ break;
145
+ case "change_text":
146
+ if (!headers["content-type"]?.includes("text/html")) {
147
+ console.error(`[change_text] Content-Type is not text/html`);
148
+ actionStatus = "fail";
149
+ }
150
+ else {
151
+ body = action.config;
152
+ console.log(`[change_text] HTML body replaced`);
153
+ }
154
+ break;
155
+ case "assert_json":
156
+ if (!json) {
157
+ console.error(`[assert_json] Response is not JSON`);
158
+ actionStatus = "fail";
159
+ }
160
+ else {
161
+ for (const check of action.config) {
162
+ const actual = getValue(json, check.path);
163
+ const expected = check.expected;
164
+ if (JSON.stringify(actual) !== JSON.stringify(expected)) {
165
+ console.error(`[assert_json] Path ${check.path}: expected ${expected}, got ${actual}`);
166
+ actionStatus = "fail";
167
+ }
168
+ else {
169
+ console.log(`[assert_json] Assertion passed for path ${check.path}`);
170
+ }
171
+ }
172
+ }
173
+ break;
174
+ case "assert_text":
175
+ if (typeof body !== "string") {
176
+ console.error(`[assert_text] Body is not text`);
177
+ actionStatus = "fail";
178
+ }
179
+ else {
180
+ if (action.config.contains && !body.includes(action.config.contains)) {
181
+ console.error(`[assert_text] Expected to contain: "${action.config.contains}"`);
182
+ actionStatus = "fail";
183
+ }
184
+ else if (action.config.equals && body !== action.config.equals) {
185
+ console.error(`[assert_text] Expected exact match`);
186
+ actionStatus = "fail";
187
+ }
188
+ else {
189
+ console.log(`[assert_text] Assertion passed`);
190
+ }
191
+ }
192
+ break;
193
+ default:
194
+ console.warn(`Unknown action type: ${action.type}`);
195
+ }
196
+ actionResults.push({ type: action.type, description, status: actionStatus });
197
+ }
198
+ tracking.completed = true;
199
+ tracking.actionResults = actionResults;
200
+ if (tracking.timer)
201
+ clearTimeout(tracking.timer);
202
+ const responseBody = json ? JSON.stringify(json) : body;
203
+ await route.fulfill({ status, body: responseBody, headers });
204
+ });
205
+ }
206
+ export async function registerAfterStepRoutes(context) {
207
+ const state = context.__routeState;
208
+ if (!state)
209
+ return [];
210
+ const mandatoryRoutes = state.matched.filter((tracked) => tracked.routeItem.mandatory);
211
+ if (mandatoryRoutes.length === 0) {
212
+ context.__routeState = null;
213
+ return [];
214
+ }
215
+ const maxTimeout = Math.max(...mandatoryRoutes.map((r) => r.routeItem.timeout));
216
+ const startTime = Date.now();
217
+ await new Promise((resolve) => {
218
+ const interval = setInterval(() => {
219
+ const allCompleted = mandatoryRoutes.every((r) => r.completed);
220
+ const elapsed = Date.now() - startTime;
221
+ if (allCompleted || elapsed >= maxTimeout) {
222
+ mandatoryRoutes.forEach((r) => {
223
+ if (!r.completed) {
224
+ console.error(`[MANDATORY] Request to ${r.routeItem.filters.path} did not complete within ${r.routeItem.timeout}ms`);
225
+ }
226
+ });
227
+ clearInterval(interval);
228
+ resolve();
229
+ }
230
+ }, 100);
231
+ });
232
+ const results = mandatoryRoutes.map((tracked) => {
233
+ const { routeItem, url, completed, actionResults = [] } = tracked;
234
+ const actions = actionResults.map((ar) => {
235
+ let status = ar.status;
236
+ if (!completed)
237
+ status = "timeout";
238
+ return {
239
+ type: ar.type,
240
+ description: ar.description,
241
+ status,
242
+ };
243
+ });
244
+ let overallStatus;
245
+ if (!completed) {
246
+ overallStatus = "timeout";
247
+ }
248
+ else if (actions.some((a) => a.status === "fail")) {
249
+ overallStatus = "fail";
250
+ }
251
+ else {
252
+ overallStatus = "success";
253
+ }
254
+ return {
255
+ url,
256
+ filters: routeItem.filters,
257
+ actions,
258
+ overallStatus,
259
+ };
260
+ });
261
+ try {
262
+ await context.web.page.unroute("**/*");
263
+ }
264
+ catch (e) {
265
+ console.error("Failed to unroute:", e);
266
+ }
267
+ context.__routeState = null;
268
+ context.routeResults = results;
269
+ return results;
270
+ }
271
+ // Helper functions
272
+ const toCucumberExpression = (text) => text.replaceAll("/", "\\\\/").replaceAll("(", "\\\\(").replaceAll("{", "\\\\{");
273
+ function extractQuotedText(inputString) {
274
+ const regex = /("[^"]*")/g;
275
+ let matches = [];
276
+ let match;
277
+ const regexInside = /"\/(.*?)\/"/g;
278
+ while ((match = regexInside.exec(inputString)) !== null) {
279
+ matches.push(match[0]);
280
+ }
281
+ while ((match = regex.exec(inputString)) !== null) {
282
+ matches.push(match[1]);
283
+ }
284
+ return matches;
285
+ }
286
+ function _stepNameToTemplate(stepName) {
287
+ if (stepName.includes("{string}")) {
288
+ return stepName;
289
+ }
290
+ let result = toCucumberExpression(stepName);
291
+ const texts = extractQuotedText(result);
292
+ texts.forEach((t) => {
293
+ result = result.replace(t, "{string}");
294
+ });
295
+ return result;
296
+ }
297
+ async function folderExists(path) {
298
+ try {
299
+ const stat = await fs.stat(path);
300
+ return stat.isDirectory();
301
+ }
302
+ catch (err) {
303
+ return false;
304
+ }
305
+ }
306
+ const getValue = (data, pattern) => {
307
+ const path = pattern.split(".");
308
+ let lengthExists = false;
309
+ if (path[path.length - 1] === "length") {
310
+ path.pop();
311
+ lengthExists = true;
312
+ }
313
+ const value = objectPath.get(data, pattern);
314
+ if (lengthExists && Array.isArray(value)) {
315
+ return value?.length;
316
+ }
317
+ else if (hasValue(value)) {
318
+ return value;
319
+ }
320
+ return undefined;
321
+ };
322
+ const hasValue = (value) => {
323
+ return value !== undefined;
324
+ };
325
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../src/route.ts"],"names":[],"mappings":"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"}