ff-automationv2 2.2.14 โ†’ 2.2.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.
Files changed (94) hide show
  1. package/dist/ai/llmprompts/systemPrompts/combinedActionExtractorPromptMob.js +4 -3
  2. package/dist/ai/llmprompts/systemPrompts/errorDescriptionPrompt.js +9 -11
  3. package/dist/ai/llmprompts/systemPrompts/fireflinkElementIndexExtactors.js +7 -7
  4. package/dist/ai/llmprompts/systemPrompts/fireflinkElementIndexExtractor_Mob.js +39 -0
  5. package/dist/ai/llmprompts/systemPrompts/mobileKeywordExtractor.js +2 -1
  6. package/dist/ai/llmprompts/systemPrompts/verifyActionExtractorPromptMob.js +2 -1
  7. package/dist/ai/llmprompts/systemPrompts/visionPrompt.js +3 -2
  8. package/dist/ai/llmprompts/systemPrompts/waitActionExtractorPrompt.js +1 -0
  9. package/dist/ai/llmprompts/systemPrompts/waitActionExtractorPromptMob.js +1 -0
  10. package/dist/automation/actions/executor.d.ts +19 -1
  11. package/dist/automation/actions/executor.js +303 -1
  12. package/dist/automation/actions/interaction/click/MOB_DoubleTapAtSpecifiedLocation.d.ts +2 -0
  13. package/dist/automation/actions/interaction/click/MOB_DoubleTapAtSpecifiedLocation.js +26 -0
  14. package/dist/automation/actions/interaction/elementLessAction/MobCheckIfAppIsClosed.d.ts +2 -0
  15. package/dist/automation/actions/interaction/elementLessAction/MobCheckIfAppIsClosed.js +20 -0
  16. package/dist/automation/actions/interaction/elementLessAction/MobRunAppInBackgroundInterface.d.ts +2 -0
  17. package/dist/automation/actions/interaction/elementLessAction/MobRunAppInBackgroundInterface.js +18 -0
  18. package/dist/automation/actions/interaction/enterActions/EnterInputIntoElementFromClipBoardInterface_mob.d.ts +2 -0
  19. package/dist/automation/actions/interaction/enterActions/EnterInputIntoElementFromClipBoardInterface_mob.js +26 -0
  20. package/dist/automation/actions/interaction/enterActions/enterInput.js +2 -2
  21. package/dist/automation/actions/interaction/enterActions/enterInputAndPress.js +1 -1
  22. package/dist/automation/actions/interaction/enterActions/enterusingJs.js +1 -1
  23. package/dist/automation/actions/interaction/enterActions/waitAndEnter.js +3 -3
  24. package/dist/automation/actions/interaction/find/MOB_FindElement.d.ts +2 -0
  25. package/dist/automation/actions/interaction/find/MOB_FindElement.js +34 -0
  26. package/dist/automation/actions/interaction/find/findElements.js +16 -2
  27. package/dist/automation/actions/interaction/get/getScreenshot.js +14 -16
  28. package/dist/automation/actions/interaction/get/getScreenshotAs.js +26 -16
  29. package/dist/automation/actions/interaction/pinch/PinchInByPercentMob.d.ts +2 -0
  30. package/dist/automation/actions/interaction/pinch/PinchInByPercentMob.js +27 -0
  31. package/dist/automation/actions/interaction/pinch/PinchOutByPercentMob.d.ts +2 -0
  32. package/dist/automation/actions/interaction/pinch/PinchOutByPercentMob.js +27 -0
  33. package/dist/automation/actions/interaction/press/mobPressBackSpaceKey.d.ts +2 -0
  34. package/dist/automation/actions/interaction/press/mobPressBackSpaceKey.js +16 -0
  35. package/dist/automation/actions/interaction/press/mobPressSpaceKey.d.ts +2 -0
  36. package/dist/automation/actions/interaction/press/mobPressSpaceKey.js +16 -0
  37. package/dist/automation/actions/interaction/swipe/swipeDirectionNTimes.d.ts +2 -0
  38. package/dist/automation/actions/interaction/swipe/swipeDirectionNTimes.js +27 -0
  39. package/dist/automation/actions/interaction/swipe/swipeDownToElement.d.ts +2 -0
  40. package/dist/automation/actions/interaction/swipe/swipeDownToElement.js +46 -0
  41. package/dist/automation/actions/interaction/swipe/swipeLeftToElement.d.ts +2 -0
  42. package/dist/automation/actions/interaction/swipe/swipeLeftToElement.js +46 -0
  43. package/dist/automation/actions/interaction/swipe/swipeRightToElement.d.ts +2 -0
  44. package/dist/automation/actions/interaction/swipe/swipeRightToElement.js +46 -0
  45. package/dist/automation/actions/interaction/swipe/swipeUpToElement.d.ts +2 -0
  46. package/dist/automation/actions/interaction/swipe/swipeUpToElement.js +49 -0
  47. package/dist/automation/actions/interaction/swipe/swipeUpToElementForMWeb.d.ts +2 -0
  48. package/dist/automation/actions/interaction/swipe/swipeUpToElementForMWeb.js +48 -0
  49. package/dist/automation/actions/interaction/swipe/swipeUsingReferenceElement.d.ts +2 -0
  50. package/dist/automation/actions/interaction/swipe/swipeUsingReferenceElement.js +140 -0
  51. package/dist/automation/actions/interaction/verify/VerifyElementNotContainsText.js +2 -2
  52. package/dist/automation/actions/interaction/wait/waitTillElementIsClickable.js +5 -1
  53. package/dist/automation/actions/interaction/wait/waitTillPresenceOfElement.js +1 -1
  54. package/dist/automation/actions/interface/clickActionInterface.d.ts +8 -0
  55. package/dist/automation/actions/interface/elelementLessActionInterface.d.ts +12 -0
  56. package/dist/automation/actions/interface/elelementLessActionInterface.js +1 -0
  57. package/dist/automation/actions/interface/findActionInterface.d.ts +10 -2
  58. package/dist/automation/actions/interface/interactionActionInterface.d.ts +8 -0
  59. package/dist/automation/actions/interface/pinchActionInterface.d.ts +19 -0
  60. package/dist/automation/actions/interface/pinchActionInterface.js +1 -0
  61. package/dist/automation/actions/interface/pressActionInterface.d.ts +10 -0
  62. package/dist/automation/actions/interface/swipeActionInterface.d.ts +89 -0
  63. package/dist/automation/actions/interface/swipeActionInterface.js +1 -0
  64. package/dist/automation/actions/interface/waitActionInterface.d.ts +1 -0
  65. package/dist/core/constants/allAction.js +1 -0
  66. package/dist/core/constants/supportedActions.js +9 -1
  67. package/dist/core/interfaces/actionInterface.d.ts +19 -1
  68. package/dist/core/interfaces/executionDetails.d.ts +1 -4
  69. package/dist/core/interfaces/fireflinkScriptPayloadInterface.d.ts +2 -3
  70. package/dist/core/main/actionHandlerFactory.js +62 -2
  71. package/dist/core/main/runAutomationScript.d.ts +0 -1
  72. package/dist/core/main/runAutomationScript.js +17 -13
  73. package/dist/service/fireflink.service.d.ts +2 -4
  74. package/dist/service/fireflink.service.js +4 -5
  75. package/dist/service/kafka/fireflinkKafka.service.d.ts +2 -2
  76. package/dist/service/kafka/fireflinkKafka.service.js +17 -3
  77. package/dist/tests/itertaion.d.ts +1 -0
  78. package/dist/tests/itertaion.js +43 -0
  79. package/dist/tests/start_iteration_suggestion.d.ts +6 -0
  80. package/dist/tests/start_iteration_suggestion.js +46 -0
  81. package/dist/tests/test1.js +0 -1
  82. package/dist/tests/test12.js +26 -75
  83. package/dist/tests/test254.d.ts +1 -0
  84. package/dist/tests/test254.js +82 -0
  85. package/dist/tests/test3.js +2 -1
  86. package/dist/tests/tests.data.d.ts +1 -0
  87. package/dist/tests/tests.data.js +5 -0
  88. package/dist/utils/logger/logData.d.ts +1 -0
  89. package/dist/utils/logger/logData.js +49 -22
  90. package/dist/utils/swipe/domSearchHelper.d.ts +5 -0
  91. package/dist/utils/swipe/domSearchHelper.js +42 -0
  92. package/dist/utils/swipe/swipeMovement.d.ts +1 -0
  93. package/dist/utils/swipe/swipeMovement.js +81 -0
  94. package/package.json +3 -4
@@ -907,8 +907,14 @@ export function createActionHandlers(context) {
907
907
  MOB_PressBackKey: withExecutor(async (executor) => {
908
908
  await executor.MOB_PressBackKey();
909
909
  }),
910
- WaitTillPresenceOfElement: withExecutor(async (executor, result) => {
911
- await executor.WaitTillPresenceOfElement(result.pageDOM, result.selector, result.fireflinkIndex, result.elementName, result.elementType);
910
+ MOB_PressBackSpaceKey: withExecutor(async (executor) => {
911
+ await executor.MOB_PressBackSpaceKey();
912
+ }),
913
+ MOB_PressSpaceKey: withExecutor(async (executor) => {
914
+ await executor.MOB_PressSpaceKey();
915
+ }),
916
+ WaitTillPresenceOfElement: withExecutor(async (executor, args) => {
917
+ await executor.WaitTillPresenceOfElement(args.pageDOM, args.selector, args.value, args.fireflinkIndex, args.elementName, args.elementType);
912
918
  }),
913
919
  WaitTillPresenceOfAllElements: withExecutor(async (executor, result) => {
914
920
  await executor.WaitTillPresenceOfAllElements(result.pageDOM, result.selector, result.value, result.fireflinkIndex, result.elementName, result.elementType);
@@ -928,6 +934,9 @@ export function createActionHandlers(context) {
928
934
  FindElements: withExecutor(async (executor, result) => {
929
935
  await executor.FindElements(result.pageDOM, result.selector, result.value, result.fireflinkIndex, result.elementName, result.elementType);
930
936
  }),
937
+ MOB_FindElement: withExecutor(async (executor, result) => {
938
+ await executor.MOB_FindElement(result.selector, result.elementName, result.elementType);
939
+ }),
931
940
  WaitTillElementIsClickable: withExecutor(async (executor, result) => {
932
941
  await executor.WaitTillElementIsClickable(result.pageDOM, result.selector, result.fireflinkIndex, result.elementName, result.elementType);
933
942
  }),
@@ -937,6 +946,9 @@ export function createActionHandlers(context) {
937
946
  PressAnyKey: withExecutor(async (executor, result) => {
938
947
  await executor.PressAnyKey(result.value);
939
948
  }),
949
+ MOB_WaitTillPresenceOfElement: withExecutor(async (executor, args) => {
950
+ await executor.WaitTillPresenceOfElement(args.pageDOM, args.selector, args.value, args.fireflinkIndex, args.elementName, args.elementType);
951
+ }),
940
952
  WaitTillElementHasText: withExecutor(async (executor, result) => {
941
953
  await executor.WaitTillElementHasText(result.pageDOM, result.selector, result.fireflinkIndex, result.elementName, result.elementType);
942
954
  }),
@@ -1108,5 +1120,53 @@ export function createActionHandlers(context) {
1108
1120
  MOB_SetEmulatorPowerPercentage: withExecutor(async (executor, result) => {
1109
1121
  await executor.MOB_SetEmulatorPowerPercentage(result.value);
1110
1122
  }),
1123
+ MOB_SwipeToElement: withExecutor(async (executor, result) => {
1124
+ await executor.swipeToElement(result.value, result.elementName, result.elementType, result.num_of_scrolls);
1125
+ }),
1126
+ MOB_SwipeUpToElement: withExecutor(async (executor, result) => {
1127
+ await executor.swipeUpToElement(result.value, result.elementName, result.elementType, result.num_of_scrolls);
1128
+ }),
1129
+ MOB_SwipeDownToElement: withExecutor(async (executor, result) => {
1130
+ await executor.swipeDownToElement(result.value, result.elementName, result.elementType, result.num_of_scrolls);
1131
+ }),
1132
+ MOB_SwipeLeftToElement: withExecutor(async (executor, result) => {
1133
+ await executor.swipeLeftToElement(result.value, result.elementName, result.elementType, result.num_of_scrolls);
1134
+ }),
1135
+ MOB_SwipeRightToElement: withExecutor(async (executor, result) => {
1136
+ await executor.swipeRightToElement(result.value, result.elementName, result.elementType, result.num_of_scrolls);
1137
+ }),
1138
+ MOB_SwipeNTimes: withExecutor(async (executor, result) => {
1139
+ await executor.swipeNTimes(result.num_of_scrolls, result.direction);
1140
+ }),
1141
+ MOB_Builtin_Swipe: withExecutor(async (executor, result) => {
1142
+ await executor.swipeDirectionNTimes(result.num_of_scrolls, result.direction);
1143
+ }),
1144
+ MOB_SwipeDirectionNTimes: withExecutor(async (executor, result) => {
1145
+ await executor.swipeDirectionNTimes(result.num_of_scrolls, result.direction);
1146
+ }),
1147
+ MOB_SwipeToElementForMWeb: withExecutor(async (executor, result) => {
1148
+ await executor.swipeToElementForMWeb(result.value, result.elementName, result.elementType);
1149
+ }),
1150
+ MOB_SwipeUsingReferenceElement: withExecutor(async (executor, result) => {
1151
+ await executor.swipeUsingReferenceElement(result.value, result.elementName, result.elementType, result.num_of_scrolls, result.direction);
1152
+ }),
1153
+ MOB_EnterInputIntoElementFromClipBoard: withExecutor(async (executor, result) => {
1154
+ await executor.MOB_EnterInputIntoElementFromClipBoard(result.selector, result.elementName, result.elementType);
1155
+ }),
1156
+ MOB_CheckIfAppIsClosed: withExecutor(async (executor) => {
1157
+ await executor.MOB_CheckIfAppIsClosed();
1158
+ }),
1159
+ MOB_RunAppInBackground: withExecutor(async (executor, result) => {
1160
+ await executor.MOB_RunAppInBackground(result.value);
1161
+ }),
1162
+ MOB_PinchInByPercent: withExecutor(async (executor, result) => {
1163
+ await executor.MOB_PinchInByPercent(result.selector, result.value, result.elementName, result.elementType);
1164
+ }),
1165
+ MOB_PinchOutByPercent: withExecutor(async (executor, result) => {
1166
+ await executor.MOB_PinchOutByPercent(result.selector, result.value, result.elementName, result.elementType);
1167
+ }),
1168
+ MOB_DoubleTapAtSpecifiedLocation: withExecutor(async (executor, result) => {
1169
+ await executor.MOB_DoubleTapAtSpecifiedLocation(result.value, result.elementName, result.elementType);
1170
+ }),
1111
1171
  };
1112
1172
  }
@@ -2,7 +2,6 @@ import { IAutomationRunner } from "../interfaces/automationRunnerInterface.js";
2
2
  import { AutomationRequest } from "../../core/interfaces/executionDetails.js";
3
3
  export declare class AutomationRunner implements IAutomationRunner {
4
4
  static sessionTerminationDetails: Record<string, boolean>;
5
- private usedElementNames;
6
5
  private KafkaPayload;
7
6
  static getSessionTerminationInfo(testCaseId: string): boolean;
8
7
  static updateSessionTerminationInfo(testCaseId: string): void;
@@ -19,13 +19,12 @@ import { isAlertPresent } from "../../utils/alertPopup/isAlertPresent.js";
19
19
  import { TOAST_WATCHER_JS } from "../../utils/javascript/jsForToaster.js";
20
20
  import { Find_element_by_ff_js_script } from "../../utils/javascript/jsFindElement.js";
21
21
  import { getFFIndexAndXPath } from "../../utils/helpers/xpathcreation.js";
22
- import { logger } from "../../utils/logger/logData.js";
22
+ import { initLogger, logger } from "../../utils/logger/logData.js";
23
23
  import { sameActionHelper } from "../../utils/helpers/sameActionsHelper.js";
24
24
  import { error } from "node:console";
25
25
  import { annotateScreenshot } from "../../imageAnalysisMobile/annotatedScreenshotMobile.js";
26
26
  export class AutomationRunner {
27
27
  constructor() {
28
- this.usedElementNames = [];
29
28
  this.KafkaPayload = {};
30
29
  }
31
30
  static getSessionTerminationInfo(testCaseId) {
@@ -50,7 +49,9 @@ export class AutomationRunner {
50
49
  },
51
50
  web: async () => {
52
51
  if (request.isCloud) {
53
- await driver.deleteSession();
52
+ if (driver?.sessionId) {
53
+ await driver.deleteSession();
54
+ }
54
55
  logger.info("Cloud session closed");
55
56
  }
56
57
  if (driver?.sessionId) {
@@ -79,13 +80,14 @@ export class AutomationRunner {
79
80
  }
80
81
  }
81
82
  async run(request) {
82
- this.usedElementNames = [];
83
+ const usedElementNames = [];
84
+ initLogger(request.sessionPath);
83
85
  if (request.isTerminate)
84
86
  return AutomationRunner.updateSessionTerminationInfo(request.testCaseId);
85
87
  AutomationRunner.sessionTerminationDetails[request.testCaseId] = request.isTerminate;
86
88
  const apiService = new FireFlinkApiService();
87
- const fireflinkServiceInstance = new fireflinkService(apiService, request.kafkaProducerInstance);
88
- const instanceDetails = await fireflinkServiceInstance.runGetInstancesDetails(request.projectId, request.token, request.serverHost);
89
+ const fireflinkServiceInstance = new fireflinkService(apiService);
90
+ const instanceDetails = await fireflinkServiceInstance.runGetInstancesDetails(request.projectId, request.token, request.serverData);
89
91
  const aiInfo = getAiInstanceInfo(instanceDetails.responseObject);
90
92
  const context = new ExecutionContext(request);
91
93
  const configProvider = new ServiceProviderBaseUrlProvider();
@@ -139,13 +141,13 @@ export class AutomationRunner {
139
141
  const baseName = elementName;
140
142
  let newName = baseName;
141
143
  let count = 0;
142
- while (this.usedElementNames.includes(newName)) {
144
+ while (usedElementNames.includes(newName)) {
143
145
  count++;
144
146
  newName = `${baseName}_${count}`;
145
147
  }
146
148
  elementName = newName;
147
149
  result.response.elementName = elementName;
148
- this.usedElementNames.push(elementName);
150
+ usedElementNames.push(elementName);
149
151
  }
150
152
  if (!allKeywordAction.includes(action)) {
151
153
  throw new Error(`Unsupported action at action or keyword exracter: ${action}`);
@@ -551,26 +553,28 @@ export class AutomationRunner {
551
553
  licenseType: request.licenseType,
552
554
  licenseId: request.licenseId,
553
555
  userId: request.userId,
554
- topic: request.topic,
555
556
  projectType: request.projectType,
556
557
  tokensConsumed: (await stepProcessor.getResultTokenUsage()).totalTokens,
557
- errorInfo: errorInfo
558
+ ...(errorInfo && Object.keys(errorInfo).length > 0 && { errorInfo })
558
559
  };
559
560
  try {
560
561
  await context.scriptAppender.waitForAllSteps();
561
- this.KafkaPayload.topic = request.topic;
562
+ // logger.info(context.scriptAppender.getData(), payload)
563
+ this.KafkaPayload.topic = `Topic-FIREFLINK-api-requests-${request.serverHost}`;
562
564
  this.KafkaPayload.message = {
563
565
  ...payload,
564
566
  scriptGenerationData: context.scriptAppender.getData(),
565
567
  serverHost: request.serverHost
566
568
  };
569
+ logger.info(this.KafkaPayload);
567
570
  await fireflinkServiceInstance.produceMessageToKafka(this.KafkaPayload);
568
571
  }
569
572
  catch (error) {
570
- throw new Error("Failed to send payload to FireFlink API:", { cause: error });
573
+ throw new Error("Failed to produce message :", { cause: error });
571
574
  }
572
575
  finally {
573
- await this.cleanup(context, domInfo, extractedRelevantDom, stepProcessor, fireflinkServiceInstance, request, platform, await context.session.getCurrentDriver() ?? await context.androidSession.getCurrentDriver());
576
+ await this.cleanup(context, domInfo, extractedRelevantDom, stepProcessor, fireflinkServiceInstance, request, platform, (await context.session.getCurrentDriver().catch(() => null)) ??
577
+ (await context.androidSession.getCurrentDriver().catch(() => null)));
574
578
  }
575
579
  }
576
580
  }
@@ -1,10 +1,8 @@
1
1
  import { IFireflinkService, IFireFlinkApiService, IKafkaPayload } from "../core/interfaces/fireflinkScriptPayloadInterface.js";
2
- import { Producer } from "kafkajs";
3
2
  export declare class fireflinkService implements IFireflinkService {
4
3
  private apiService;
5
- private kafkaProducerInstance;
6
4
  private kafkaProducer;
7
- constructor(apiService: IFireFlinkApiService, kafkaProducerInstance: Producer);
8
- runGetInstancesDetails(projectId: string, token: string, serverHost: string): Promise<any>;
5
+ constructor(apiService: IFireFlinkApiService);
6
+ runGetInstancesDetails(projectId: string, token: string, serverData: string): Promise<any>;
9
7
  produceMessageToKafka(kafkaArgs: IKafkaPayload): Promise<void>;
10
8
  }
@@ -1,12 +1,11 @@
1
1
  import { KafkaProducerService } from "./kafka/fireflinkKafka.service.js";
2
2
  import { logger } from "../utils/logger/logData.js";
3
3
  export class fireflinkService {
4
- constructor(apiService, kafkaProducerInstance) {
4
+ constructor(apiService) {
5
5
  this.apiService = apiService;
6
- this.kafkaProducerInstance = kafkaProducerInstance;
7
- this.kafkaProducer = new KafkaProducerService(this.kafkaProducerInstance);
6
+ this.kafkaProducer = new KafkaProducerService();
8
7
  }
9
- async runGetInstancesDetails(projectId, token, serverHost) {
8
+ async runGetInstancesDetails(projectId, token, serverData) {
10
9
  const headers = {
11
10
  Accept: "*/*",
12
11
  "Accept-Language": "en-US,en;q=0.9",
@@ -14,7 +13,7 @@ export class fireflinkService {
14
13
  projectId: projectId || "",
15
14
  Authorization: `Bearer ${token}`,
16
15
  };
17
- const url = `${serverHost}/project/optimize/v3/ai-service-provider/selected-instance?projectId=${projectId}`;
16
+ const url = `${serverData}/project/optimize/v3/ai-service-provider/selected-instance?projectId=${projectId}`;
18
17
  try {
19
18
  const finalResult = await this.apiService.getInstancesDetailsApi(headers, url);
20
19
  if (finalResult) {
@@ -1,7 +1,7 @@
1
- import { Producer } from "kafkajs";
2
1
  import { IKafkaPayload } from "../../core/interfaces/fireflinkScriptPayloadInterface.js";
3
2
  export declare class KafkaProducerService {
3
+ private kafka;
4
4
  private kafkaProducer;
5
- constructor(kafkaProducer: Producer | any);
5
+ constructor();
6
6
  produceMessage(kafkaArgs: IKafkaPayload): Promise<void>;
7
7
  }
@@ -1,7 +1,21 @@
1
+ import { Kafka } from "kafkajs";
1
2
  import { logger } from "../../utils/logger/logData.js";
3
+ import fs from "fs";
4
+ import dotenv from "dotenv";
5
+ dotenv.config();
2
6
  export class KafkaProducerService {
3
- constructor(kafkaProducer) {
4
- this.kafkaProducer = kafkaProducer;
7
+ constructor() {
8
+ this.kafka = new Kafka({
9
+ clientId: process.env.KAFKA_CLIENT_ID,
10
+ brokers: process.env.KAFKA_BROKERS.split(","),
11
+ ssl: {
12
+ ca: [fs.readFileSync(process.env.KAFKA_SSL_CA, "utf-8")],
13
+ key: fs.readFileSync(process.env.KAFKA_SSL_KEY, "utf-8"),
14
+ cert: fs.readFileSync(process.env.KAFKA_SSL_CERT, "utf-8"),
15
+ rejectUnauthorized: true,
16
+ },
17
+ });
18
+ this.kafkaProducer = this.kafka.producer();
5
19
  }
6
20
  async produceMessage(kafkaArgs) {
7
21
  try {
@@ -12,7 +26,7 @@ export class KafkaProducerService {
12
26
  messages: [{ value: JSON.stringify(kafkaArgs.message) }],
13
27
  });
14
28
  await this.kafkaProducer.disconnect();
15
- logger.info("Kafka produced message successfully and Kafka produced disconnected successfully");
29
+ logger.info("Kafka produced message successfully and Kafka producer disconnected successfully");
16
30
  }
17
31
  catch (error) {
18
32
  await this.kafkaProducer.disconnect();
@@ -0,0 +1 @@
1
+ declare let system_prompt: string;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ let system_prompt = `You are given a 2D array of test steps. Each step is an array where the first element is a string describing the action, and optional additional elements may contain variable references.
3
+
4
+ Your task is to extract structured data based on the following rules:
5
+
6
+ 1. Find the FIRST occurrence of a step whose text contains "start iteration" (case-insensitive).
7
+ 2. From that point, begin collecting all steps.
8
+ 3. Continue collecting until you encounter the FIRST occurrence of a step whose text contains "End iteration" (case-insensitive) AFTER the start.
9
+ 4. Include both the "start iteration" and "End iteration" steps.
10
+ 5. STOP immediately after the first "End iteration".
11
+ 6. Ignore all steps before and after this block.
12
+
13
+ Data extraction rules:
14
+ 7. From the "start iteration" step, extract the instance name inside single quotes.
15
+ Example: "start iteration using 'Data1' Dataprovider" โ†’ instanceName = "Data1"
16
+
17
+ 8. From each step, if a second element exists and contains text like "Dataprovider <variableName>", extract the variable name.
18
+ Example: "Dataprovider val1" โ†’ "val1"
19
+
20
+ 9. Collect all variable names into a list called "variables" (preserve order).
21
+
22
+ Output format (STRICT):
23
+
24
+ * Return ONLY valid JSON
25
+ * No explanations or extra text
26
+ * Use this exact structure:
27
+
28
+ {
29
+ "instanceName": "string",
30
+ "variables": ["var1", "var2"],
31
+ "steps": [ ...extracted steps... ]
32
+ }
33
+
34
+ Edge cases:
35
+
36
+ * If no valid block is found, return:
37
+ {
38
+ "instanceName": "",
39
+ "variables": [],
40
+ "steps": []
41
+ }
42
+
43
+ `;
@@ -0,0 +1,6 @@
1
+ declare function findMaxNonNestedPatterns<T>(arr: T[]): {
2
+ pattern: T[];
3
+ count: number;
4
+ startIndexes: number[];
5
+ }[];
6
+ declare const arr: number[];
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ function findMaxNonNestedPatterns(arr) {
3
+ const results = [];
4
+ let i = 0;
5
+ while (i < arr.length) {
6
+ let best = null;
7
+ for (let size = 1; size <= Math.floor((arr.length - i) / 2); size++) {
8
+ const pattern = arr.slice(i, i + size);
9
+ let j = i;
10
+ let count = 0;
11
+ const indexes = [];
12
+ while (j + size <= arr.length) {
13
+ let match = true;
14
+ for (let k = 0; k < size; k++) {
15
+ if (arr[j + k] !== pattern[k]) {
16
+ match = false;
17
+ break;
18
+ }
19
+ }
20
+ if (!match)
21
+ break;
22
+ indexes.push(j);
23
+ count++;
24
+ j += size;
25
+ }
26
+ if (count > 1) {
27
+ // ๐Ÿ”ฅ Keep ONLY longest pattern (removes nested duplicates)
28
+ if (!best || pattern.length > best.pattern.length) {
29
+ best = { pattern, count, startIndexes: indexes };
30
+ }
31
+ }
32
+ }
33
+ if (best) {
34
+ results.push(best);
35
+ // ๐Ÿ”ฅ Skip entire block (avoid re-detection)
36
+ const last = best.startIndexes[best.startIndexes.length - 1];
37
+ i = last + best.pattern.length;
38
+ }
39
+ else {
40
+ i++;
41
+ }
42
+ }
43
+ return results;
44
+ }
45
+ const arr = [1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2];
46
+ console.log(findMaxNonNestedPatterns(arr));
@@ -9,5 +9,4 @@ sessionList = sessionList.filter(item => !(item.testCase === "B" && item.env ===
9
9
  const founds1 = sessionList.some(item => item.testCase === "A" &&
10
10
  item.env === "local" &&
11
11
  item.isTerminate === false);
12
- // console.log(founds); // undefined
13
12
  console.log(sessionList);
@@ -1,18 +1,27 @@
1
1
  import { AutomationRunner } from "../index.js";
2
- import { Kafka } from "kafkajs";
3
- const kafka = new Kafka({
4
- clientId: "automation-service",
5
- brokers: ["127.0.0.1:9092"],
6
- });
7
- const producer = kafka.producer();
2
+ import path from "path";
8
3
  const runner = new AutomationRunner();
9
4
  runner.run({
10
5
  userStory: [
11
6
  ["Open browser"],
12
7
  ["Navigate to https://www.google.com/"],
13
8
  ["Maximize the browser"],
14
- ["enter asdfdsas in search field"],
15
- ["Close browser"]
9
+ // ["Navigate to https://www.google.com/"],
10
+ // ["Maximize the browser"],
11
+ // ["Navigate to https://www.google.com/"],
12
+ // ["Maximize the browser"],
13
+ // ["click on Gmail link"],
14
+ ["Close browser"],
15
+ // ["start iteration using 'Data1' Dataprovider"],
16
+ // ["enter 'startIteration1' in search field"],
17
+ // ["enter level-A in search field"],
18
+ // ["start iteration using 'Data1' Dataprovider"],
19
+ // ["enter 'startIteration1' in search field"],
20
+ // ["enter level-B in search field"],
21
+ // ["End iteration"],
22
+ // ["End iteration"],
23
+ // ["click on Gmail link"],
24
+ // ["Close browser"],
16
25
  ],
17
26
  platform: "web",
18
27
  pageDetails: {
@@ -21,81 +30,24 @@ runner.run({
21
30
  pageName: "ai-Page"
22
31
  }
23
32
  },
24
- service_accounts: "",
25
- serverHost: "https://test3.fireflink.com",
33
+ sessionPath: path.join("D:", "Bitbucket", "automationV2"),
34
+ serverHost: "test3",
35
+ // topic: "",
36
+ // serviceAccounts: "",
26
37
  webSocketId: "",
27
38
  generatedBy: "",
28
39
  licenseType: "C-Professional",
29
40
  licenseId: "LIC3985",
30
41
  userId: "USR26935",
31
- topic: "Topic-FIREFLINK-aiAutomation-Updates-test3",
32
42
  projectType: "Web",
33
43
  browser: {
34
- browserName: "edge",
35
- },
36
- serverData: {},
37
- version: "asdfg",
38
- type: "sdfg",
39
- scriptName: "url",
40
- scriptType: "android",
41
- projectId: "PJT1116",
42
- testCaseId: "SCR1208",
43
- promptId: "3f6e123c-8ec6-47c1-90e1-1a2f53b49251",
44
- userName: "default-user",
45
- appiumPort: 0,
46
- platformVersion: "",
47
- realDeviceId: "",
48
- kafkaProducerInstance: producer,
49
- isCloud: true,
50
- cloudConfig: {
51
- accessKey: "yfAa_w199cJge2Gezsgb2Jnu7hKdqER1tExY5kKvgSvXfi1lRUelFsbTFI5pMq7zQuwwNXXnsLTkjKhvWcKDWsUoGLi9KjUV6gbUNDhqj0jWYFyW9h_0LIDEg5qXigwZdqzQqAvWwHin3gBhzGndeROtixv_VFhnseGSWRAHTajZzE-Zl0d8BP6gl0TEBUfoNgqBtAQVDLP6wAQzPfcyjjGFsdHkXWeHFkKmA78D7rKlnNuN2WgjIUlhYheDRDeqZ98Ig_PyS1GbUvjwJ73L38sr_cD4Y9lrKyWJV-m5RmtKhmkqRM8uk5gEfjzgwy30",
52
- hostname: "devicefarm.fireflink.com",
53
- licenseId: "LIC2026658",
54
- projectName: "Project-6",
55
- protocol: "https",
56
- path: "backend/fireflinkcloud/wd/hub"
57
- },
58
- capabilities: {
59
44
  browserName: "chrome",
60
- platformName: "Windows 11",
61
- browserVersion: "146"
62
45
  },
63
- isTerminate: false,
64
- token: "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJRUFRfTnFuMkxxdDVmN09tOElWaW53dUJlR3ZVUUVBUkdxZkFuRHJxZU9NIn0.eyJleHAiOjE3NzQwODI1ODQsImlhdCI6MTc3Mzk5NjE4NCwianRpIjoib25ydHJvOjQ3NDBkMjRhLTQ5ZWQtNDBkOC1hNmI2LWM3MDNlMGMzMDBkNyIsImlzcyI6Imh0dHA6Ly8xMDMuMTgyLjIxMC4yMjY6MzAxMDcvcmVhbG1zL0ZpcmVGbGluay10ZXN0MyIsImF1ZCI6InRhcmdldC1jbGllbnQiLCJzdWIiOiJmOmNhMzBmNDk3LTY1Y2YtNGU4Zi1iZGE3LTE0ZjM1NTNiYzZmNTpqYWlha2FzaEB5b3BtYWlsLmNvbSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImZsaW5rLXNlcnZpY2UiLCJzaWQiOiI0NzdlZTY2NS0yODNjLTQ5NWUtODAxMy02MzQ2MGU3MzZjYzkiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsImN1cnJlbnRMaWNlbnNlSWQiOiJMSUMzOTg1IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJjdXJyZW50UHJpdmlsZWdlIjoiU3VwZXIgQWRtaW4iLCJmdWxsTmFtZSI6ImphaSIsImFjdGl2YXRpb25TdGF0dXMiOiJBQ1RJVkUiLCJwcml2aWxlZ2UiOiJTdXBlciBBZG1pbiIsImxpY2Vuc2VOYW1lIjoiRmlyZUZsaW5rIC0gTElDMzk4NSIsInByZWZlcnJlZF91c2VybmFtZSI6ImphaSIsInVzZXJOYW1lIjoiamFpYWthc2hAeW9wbWFpbC5jb20iLCJiaWxsaW5nQ3ljbGUiOiJRdWFydGVybHkiLCJpZCI6IlVTUjI2OTM1IiwibGljZW5zZUlkIjoiTElDMzk4NSIsImVtYWlsIjoiamFpYWthc2hAeW9wbWFpbC5jb20ifQ.I35oWluehCl5F2RKjvVEhOrHX20EyeKpzquPjpfkjpOEG7djVJeHbC8vrpMXadvGZrkn2h5JXurQK_Xj6LHu1qF73W1pu3_ot_PCzmy7SGJxJ7P3PCnyA1_EzF54YEuNh5dNkYSFdPOfptRiKbpwGDgeujNxTdzrQ-9rSax2IIwmajQ1jhnF1S6dPC2aJESzroy9Q1asmFwMrXvroEEcy-tyXGu6psfyicp-lPzXcBcLkLAjRHdfbmJIxflaO9CCXlurg_1_7bLlMt-7ZZa7-YVRZmJnw3DQFGdOr7krSUaVAizVWphVrcoX-slexxpSbxpVLEYTSTx_dLlHcRA75w"
65
- });
66
- await new Promise(res => setTimeout(res, 4000));
67
- runner.run({
68
- userStory: [
69
- ["Open browser"],
70
- ["Navigate to https://www.google.com/"],
71
- ["Maximize the browser"],
72
- ["enter asdfdsas in search field"],
73
- ["Close browser"]
74
- ],
75
- platform: "web",
76
- pageDetails: {
77
- Web: {
78
- pageId: "PAG73a7a0ad-c092-4351-8a93-68647f60e343",
79
- pageName: "ai-Page"
80
- }
81
- },
82
- service_accounts: "",
83
- serverHost: "https://test3.fireflink.com",
84
- webSocketId: "",
85
- generatedBy: "",
86
- licenseType: "C-Professional",
87
- licenseId: "LIC3985",
88
- userId: "USR26935",
89
- topic: "Topic-FIREFLINK-aiAutomation-Updates-test3",
90
- projectType: "Web",
91
- browser: {
92
- browserName: "edge",
93
- },
94
- serverData: {},
46
+ serverData: "https://test3.fireflink.com",
95
47
  version: "asdfg",
96
48
  type: "sdfg",
97
49
  scriptName: "url",
98
- scriptType: "android",
50
+ scriptType: "web",
99
51
  projectId: "PJT1116",
100
52
  testCaseId: "SCR1208",
101
53
  promptId: "3f6e123c-8ec6-47c1-90e1-1a2f53b49251",
@@ -103,8 +55,7 @@ runner.run({
103
55
  appiumPort: 0,
104
56
  platformVersion: "",
105
57
  realDeviceId: "",
106
- kafkaProducerInstance: producer,
107
- isCloud: true,
58
+ isCloud: false,
108
59
  cloudConfig: {
109
60
  accessKey: "yfAa_w199cJge2Gezsgb2Jnu7hKdqER1tExY5kKvgSvXfi1lRUelFsbTFI5pMq7zQuwwNXXnsLTkjKhvWcKDWsUoGLi9KjUV6gbUNDhqj0jWYFyW9h_0LIDEg5qXigwZdqzQqAvWwHin3gBhzGndeROtixv_VFhnseGSWRAHTajZzE-Zl0d8BP6gl0TEBUfoNgqBtAQVDLP6wAQzPfcyjjGFsdHkXWeHFkKmA78D7rKlnNuN2WgjIUlhYheDRDeqZ98Ig_PyS1GbUvjwJ73L38sr_cD4Y9lrKyWJV-m5RmtKhmkqRM8uk5gEfjzgwy30",
110
61
  hostname: "devicefarm.fireflink.com",
@@ -118,6 +69,6 @@ runner.run({
118
69
  platformName: "Windows 11",
119
70
  browserVersion: "146"
120
71
  },
121
- isTerminate: true,
122
- token: "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJRUFRfTnFuMkxxdDVmN09tOElWaW53dUJlR3ZVUUVBUkdxZkFuRHJxZU9NIn0.eyJleHAiOjE3NzQwODI1ODQsImlhdCI6MTc3Mzk5NjE4NCwianRpIjoib25ydHJvOjQ3NDBkMjRhLTQ5ZWQtNDBkOC1hNmI2LWM3MDNlMGMzMDBkNyIsImlzcyI6Imh0dHA6Ly8xMDMuMTgyLjIxMC4yMjY6MzAxMDcvcmVhbG1zL0ZpcmVGbGluay10ZXN0MyIsImF1ZCI6InRhcmdldC1jbGllbnQiLCJzdWIiOiJmOmNhMzBmNDk3LTY1Y2YtNGU4Zi1iZGE3LTE0ZjM1NTNiYzZmNTpqYWlha2FzaEB5b3BtYWlsLmNvbSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImZsaW5rLXNlcnZpY2UiLCJzaWQiOiI0NzdlZTY2NS0yODNjLTQ5NWUtODAxMy02MzQ2MGU3MzZjYzkiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsImN1cnJlbnRMaWNlbnNlSWQiOiJMSUMzOTg1IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJjdXJyZW50UHJpdmlsZWdlIjoiU3VwZXIgQWRtaW4iLCJmdWxsTmFtZSI6ImphaSIsImFjdGl2YXRpb25TdGF0dXMiOiJBQ1RJVkUiLCJwcml2aWxlZ2UiOiJTdXBlciBBZG1pbiIsImxpY2Vuc2VOYW1lIjoiRmlyZUZsaW5rIC0gTElDMzk4NSIsInByZWZlcnJlZF91c2VybmFtZSI6ImphaSIsInVzZXJOYW1lIjoiamFpYWthc2hAeW9wbWFpbC5jb20iLCJiaWxsaW5nQ3ljbGUiOiJRdWFydGVybHkiLCJpZCI6IlVTUjI2OTM1IiwibGljZW5zZUlkIjoiTElDMzk4NSIsImVtYWlsIjoiamFpYWthc2hAeW9wbWFpbC5jb20ifQ.I35oWluehCl5F2RKjvVEhOrHX20EyeKpzquPjpfkjpOEG7djVJeHbC8vrpMXadvGZrkn2h5JXurQK_Xj6LHu1qF73W1pu3_ot_PCzmy7SGJxJ7P3PCnyA1_EzF54YEuNh5dNkYSFdPOfptRiKbpwGDgeujNxTdzrQ-9rSax2IIwmajQ1jhnF1S6dPC2aJESzroy9Q1asmFwMrXvroEEcy-tyXGu6psfyicp-lPzXcBcLkLAjRHdfbmJIxflaO9CCXlurg_1_7bLlMt-7ZZa7-YVRZmJnw3DQFGdOr7krSUaVAizVWphVrcoX-slexxpSbxpVLEYTSTx_dLlHcRA75w"
72
+ isTerminate: false,
73
+ token: "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJRUFRfTnFuMkxxdDVmN09tOElWaW53dUJlR3ZVUUVBUkdxZkFuRHJxZU9NIn0.eyJleHAiOjE3NzUwNDMwMjcsImlhdCI6MTc3NDk1NjYyNywianRpIjoib25ydHJvOjk5MjQwN2U3LWU2ZWQtNDUwMS05NDhhLTA2YmQyMGIwZmNhZSIsImlzcyI6Imh0dHA6Ly8xMDMuMTgyLjIxMC4yMjY6MzAxMDcvcmVhbG1zL0ZpcmVGbGluay10ZXN0MyIsImF1ZCI6InRhcmdldC1jbGllbnQiLCJzdWIiOiJmOmNhMzBmNDk3LTY1Y2YtNGU4Zi1iZGE3LTE0ZjM1NTNiYzZmNTpqYWlha2FzaEB5b3BtYWlsLmNvbSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImZsaW5rLXNlcnZpY2UiLCJzaWQiOiI1NGVlNDQ0YS0zMzdkLTQwNjMtYjhlZC0yOWI2ZTFmZjBhN2YiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsImN1cnJlbnRMaWNlbnNlSWQiOiJMSUMzOTg1IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJjdXJyZW50UHJpdmlsZWdlIjoiU3VwZXIgQWRtaW4iLCJmdWxsTmFtZSI6ImphaSIsImFjdGl2YXRpb25TdGF0dXMiOiJBQ1RJVkUiLCJwcml2aWxlZ2UiOiJTdXBlciBBZG1pbiIsImxpY2Vuc2VOYW1lIjoiRmlyZUZsaW5rIC0gTElDMzk4NSIsInByZWZlcnJlZF91c2VybmFtZSI6ImphaSIsInVzZXJOYW1lIjoiamFpYWthc2hAeW9wbWFpbC5jb20iLCJiaWxsaW5nQ3ljbGUiOiJRdWFydGVybHkiLCJpZCI6IlVTUjI2OTM1IiwibGljZW5zZUlkIjoiTElDMzk4NSIsImVtYWlsIjoiamFpYWthc2hAeW9wbWFpbC5jb20ifQ.u_ZqC8OLDQCPyqd-7Y8iby0ylHJq5MRXzSxQ0fHv8ofWPYEeOW428NKJEnddddqvgGYxY-oYm9QbalDxqt3KGPnrMPfDvD1KyoVEAisZEq6N_DvN5G0OunH5pEMtubfGJVTKRlAE1OZfHETZrfe5vveKBmycJbeR8_nAdhsu3TGovAwkhGHUeeDIvR_5q0i-Rw_XasXn2Vx7T4l05kdPlu_-9a5J4MIRm3fA7IT9LV2wy63-7alnB1btx2Z4nU2yLcSWdr2gWKNz8a_ulPa2aDHZK-0AyEUtn9-WnLPwV5ZEbGcTDxt-ybN2FKnNIKrI8Ka0RGDyfTTYK50xUlNOIQ"
123
74
  });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,82 @@
1
+ import { remote } from 'webdriverio';
2
+ import { encode } from '@toon-format/toon';
3
+ import * as cheerio from 'cheerio';
4
+ import fs from 'fs';
5
+ import { encoding_for_model } from "@dqbd/tiktoken";
6
+ // ๐Ÿ”„ HTML โ†’ JSON
7
+ function htmlToJson(html) {
8
+ const $ = cheerio.load(html);
9
+ // ๐Ÿงน remove useless elements
10
+ $('script, style, noscript, iframe').remove();
11
+ function parseElement(elem, depth = 0) {
12
+ if (!elem || depth > 6)
13
+ return null;
14
+ const node = {
15
+ tag: elem.name,
16
+ attrs: elem.attribs || {},
17
+ children: [] // โœ… FIX
18
+ };
19
+ for (const child of elem.children || []) {
20
+ if (child.type === 'text') {
21
+ const text = child.data.trim();
22
+ if (text) {
23
+ node.children.push({ text });
24
+ }
25
+ }
26
+ else if (child.type === 'tag') {
27
+ const parsed = parseElement(child, depth + 1);
28
+ if (parsed) {
29
+ node.children.push(parsed);
30
+ }
31
+ }
32
+ }
33
+ return node;
34
+ }
35
+ return parseElement($('body')[0]);
36
+ }
37
+ // ๐Ÿš€ Main runner
38
+ async function run() {
39
+ const browser = await remote({
40
+ capabilities: {
41
+ browserName: 'chrome'
42
+ }
43
+ });
44
+ try {
45
+ // ๐ŸŒ Open Amazon
46
+ await browser.url('https://www.amzon.in/');
47
+ // โณ wait for search box
48
+ const searchBox = await browser.$('#twotabsearchtextbox');
49
+ await searchBox.waitForDisplayed({ timeout: 10000 });
50
+ // ๐Ÿ“„ Get HTML
51
+ const html = await browser.getPageSource();
52
+ // ๐Ÿ”„ Convert HTML โ†’ JSON
53
+ const json = htmlToJson(html);
54
+ // ๐Ÿ”„ JSON โ†’ TOON
55
+ const start = performance.now();
56
+ const encoded = encode({ data: json });
57
+ const end = performance.now();
58
+ console.log('HTML :', html.length);
59
+ console.log('json size:', JSON.stringify(json).length);
60
+ console.log('Encoded length:', encoded.length);
61
+ console.log(`Time taken: ${(end - start).toFixed(2)} ms`);
62
+ // ๐Ÿ’พ Save outputs (optional but useful)
63
+ fs.writeFileSync('output.json', JSON.stringify(json, null, 2));
64
+ fs.writeFileSync('output.toon', encoded);
65
+ const enc = encoding_for_model("gpt-4"); // closest available
66
+ function countTokens(text) {
67
+ return enc.encode(text).length;
68
+ }
69
+ const jsonString = JSON.stringify(json);
70
+ console.log("Token JSON count:", countTokens(jsonString));
71
+ const jsonStringencoded = JSON.stringify(encoded);
72
+ console.log("Token TOON count:", countTokens(jsonStringencoded));
73
+ }
74
+ catch (err) {
75
+ console.error(err);
76
+ }
77
+ finally {
78
+ await browser.deleteSession();
79
+ }
80
+ }
81
+ run();
82
+ console.log("hi");
@@ -21,4 +21,5 @@ async function runTest() {
21
21
  await browser.url("https://www.google.com");
22
22
  await browser.deleteSession();
23
23
  }
24
- runTest().catch(console.error);
24
+ runTest();
25
+ console.log("hi");
@@ -0,0 +1 @@
1
+ export declare const testdata: Record<string, any>;
@@ -0,0 +1,5 @@
1
+ export const testdata = {
2
+ Data1: {
3
+ startIteration1: [1, 2, 3],
4
+ }
5
+ };
@@ -1,3 +1,4 @@
1
+ export declare function initLogger(basePath: string): void;
1
2
  export declare const logger: {
2
3
  info: (...args: any[]) => Promise<void>;
3
4
  error: (...args: any[]) => Promise<void>;