ff-automationv2 2.2.26 → 2.2.27

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 (22) hide show
  1. package/dist/ai/llmcalls/llmAction.js +1 -1
  2. package/dist/ai/llmcalls/parseLlmOputput.js +3 -0
  3. package/dist/ai/llmprompts/systemPrompts/getActionExtractorPromptMob.js +2 -1
  4. package/dist/ai/llmprompts/systemPrompts/mobileKeywordExtractor.js +1 -1
  5. package/dist/automation/actions/executor.js +6 -0
  6. package/dist/automation/actions/interaction/enterActions/waitAndEnter.js +1 -1
  7. package/dist/automation/actions/interaction/get/getScreenshotAs.js +1 -1
  8. package/dist/automation/actions/interaction/verify/VerifyAllOptionsAreDeSelected.js +0 -6
  9. package/dist/automation/actions/interaction/verify/VerifyAttributeValue.js +1 -1
  10. package/dist/automation/actions/interaction/verify/VerifyPartialAttributeValue.js +1 -1
  11. package/dist/automation/actions/interaction/verify/checkIfElementIsDisplayed.js +1 -1
  12. package/dist/automation/actions/interaction/wait/MOB_WaitTillAttributeOfElementContainsString.js +1 -1
  13. package/dist/automation/actions/interaction/wait/waitTillAttributeOfElementIsString.js +1 -1
  14. package/dist/automation/actions/interaction/wait/waitTillElementContainsText.js +1 -1
  15. package/dist/automation/actions/interaction/wait/waitTillElementHasText.js +1 -1
  16. package/dist/automation/actions/interaction/wait/waitTillElementIsClickable.js +1 -1
  17. package/dist/automation/mobileSession/initiateMobileSession.js +1 -2
  18. package/dist/core/interfaces/fireflinkScriptPayloadInterface.d.ts +1 -1
  19. package/dist/core/main/actionHandlerFactory.js +5 -5
  20. package/dist/core/main/runAutomationScript.js +13 -4
  21. package/dist/utils/helpers/sameActionsHelper.js +1 -1
  22. package/package.json +1 -1
@@ -19,7 +19,7 @@ class llmAction {
19
19
  baseURL: baseURL,
20
20
  });
21
21
  this.visionClient = new openai_1.default({
22
- apiKey: (0, decodeApiKey_js_1.decodeApiKey)(this.visionApiKey ?? apiKey),
22
+ apiKey: (0, decodeApiKey_js_1.decodeApiKey)(this.visionApiKey ?? "c2stcHJvai1HVTVlZGt4UDJEQXVBa29IbzB0MXdsTWFrWjljNnlQQjEtdUdGLXloZmhIclhEYnZubHo0M0l4QUoyME5Pc0hGYUw2OUFkdG5kOVQzQmxia0ZKQzUxTFJZX09aQzNzRHBOYjN5XzM5SUY4UXpBZElSU2ZBQ21wZjRtZG1OUzBlWXRhUjhudGhWdUktb2djeVBSMW1PdVpEdU83UUE="),
23
23
  });
24
24
  }
25
25
  async getLLMResponse(platform, type, args, userInput) {
@@ -15,6 +15,9 @@ class LLMResultParser {
15
15
  return JSON.parse(match[0]);
16
16
  }
17
17
  async fetchResult(llmOutput) {
18
+ if (typeof llmOutput?.error === "string" && llmOutput.error.includes("429")) {
19
+ throw llmOutput;
20
+ }
18
21
  try {
19
22
  const content = llmOutput?.choices?.[0]?.message?.content;
20
23
  if (!content) {
@@ -10,7 +10,7 @@ async function getActionExtractorPromptMob({ extractedDomJson, priorAndNextSteps
10
10
  "MOB_GetBatteryStatus","MOB_GetCurrentActivity","MOB_GetDeviceOsVersion","MOB_GetDeviceUdid","MOB_GetDeviceName","MOB_GetImplicitTimeOut",
11
11
  "MOB_GetDriverInstance","MOB_GetCurrentWindowHandle","MOB_GetCurrentSessionId","MOB_GetHeightOfScreen","MOB_GetCurrentDeviceSystemBars",
12
12
  "MOB_GetAttributeValueFromListOfWebElements","MOB_GetTagName","MOB_GetListOfElementsFromLocatorTypeLocatorValue","MOB_GetScreenshot","MOB_GetTextFromElementAndSetToClipBoard",
13
- "MOB_GetHeightOfElement","MOB_GetTextFromListOfWebElements","MOB_GetHexCodeForGivenXYCoordinatesOfImage","MOB_GetADBLogsForGivenAppPackage","MOB_GetScreenshotAs","MOB_GetWidthOfElement",
13
+ "MOB_GetHeightOfElement","MOB_GetTextFromListOfWebElements","MOB_GetHexCodeForGivenXYCoordinatesOfImage","MOB_GetADBLogsForGivenAppPackage","MOB_GetScreenshotOfElement","MOB_GetWidthOfElement",
14
14
  "MOB_GetX", "MOB_GetLocation","MOB_GetY","MOB_GetPerformanceData","MOB_GetRect","MOB_GetText","GetSize","MOB_GetAttribute"`;
15
15
  const elementType = ["link", "textfield", "icon", "button", "radiobutton", "checkbox", "tab", "action overflow button", "hamburger menu", "toggle button", "steppers", "sliders"];
16
16
  const prompt = `You are an intelligent assistant that extracts structured UI action data.
@@ -36,6 +36,7 @@ Rules:
36
36
  - Extract input_text from the step, if you can't find any input text in the step, return keyword as input_text.
37
37
  ex:Fetch the ADB logs for the abhibus
38
38
  here input: abhibus
39
+ - if step is get screenshot of element map it to MOB_GetScreenshotOfElement nlp.
39
40
  - Extract keyword from the step, if the step contains any keyword.
40
41
  - Use the closest semantic match for the step; return attribute_value as Fire-Flink-0, only if nothing is found.
41
42
  - if step is get location of device or get device location then map to MOB_GetDeviceLocation nlp.
@@ -21,7 +21,7 @@ If they mention package:com.app.android and activity:com.app.activity remove var
21
21
  - Do NOT include status/technical words (displayed, enabled, authenticate, visible).
22
22
  - If an element label contains multiple words (e.g., "Sign In", "Add to Cart"), keep them together as ONE keyword and do not split them and also for keywords you generated, do not split them.
23
23
  -** element_name: extract name of the element that mentioned in the step not from keywords or other steps.(eg:tap on x -> element_name:x). always try to retuen short and meaning full element name from step**
24
- - action: openApp for opening or launching of app, tap for taping or selecting or clicking or pressing, enter for entering input, wait for waiting or sleeping, verify for verifying or checking,scroll for scrolling and swiping, get for getting,fetching element, closeApp for closing the app.
24
+ - action: openApp for opening or launching of app, tap for taping or selecting or clicking or pressing, enter for entering input, wait for waiting or sleeping, verify for verifying or checking, scroll for scrolling and swiping, get for getting,fetching element, closeApp for closing the app.
25
25
  - If step is press any key give action as tap.
26
26
  - action must be one of from this list ${allowedActions}.if not one of them, return action as 'combined'. if step about set or find or open chrome browser or open app with apk path or install apk or uninstall apk or activate or terminate action pinch in or pinch out and running app in the backgroundaction return action as 'combined'
27
27
  - if the step action is about finding then provide action as combined.
@@ -360,6 +360,12 @@ class ActionExecutor {
360
360
  this.elementGetter = elementGetter;
361
361
  this.platform = platform;
362
362
  this.adbPath = adbPath;
363
+ if (this.platform.toLowerCase() == "web") {
364
+ this.platform = "Web";
365
+ }
366
+ else if (this.platform.toLowerCase() == "android") {
367
+ this.platform = "Android";
368
+ }
363
369
  }
364
370
  async navigate(url) {
365
371
  try {
@@ -30,7 +30,7 @@ async function waitAndEnter(args) {
30
30
  elementsData: [{
31
31
  name: args.elementName,
32
32
  type: args.elementType,
33
- locators: [{ xpath: args.selector }],
33
+ locators: [{ "name": "xpath", "value": args.selector }],
34
34
  platform: args.platform
35
35
  }]
36
36
  };
@@ -18,7 +18,7 @@ const getScreenshotAs = async (args) => {
18
18
  elementsData: [{
19
19
  name: args.elementName,
20
20
  type: args.elementType,
21
- locators: [{ xpath: args.selector }],
21
+ locators: [{ "name": "xpath", "value": args.selector }],
22
22
  platform: args.platform
23
23
  }]
24
24
  }));
@@ -15,12 +15,6 @@ async function verifyAllOptionsAreDeselected(args) {
15
15
  }
16
16
  }
17
17
  logData_js_1.logger.info("All options are deselected.");
18
- logData_js_1.logger.info("All options deselection verification result:", {
19
- pagedom: args.pageDOM,
20
- fireflinkIndex: args.fireflinkIndex,
21
- elementName: args.elementName,
22
- xpath: args.selector
23
- });
24
18
  if (result === false) {
25
19
  throw new Error("Not all options are deselected.");
26
20
  }
@@ -61,7 +61,7 @@ async function verifyAttributeValue(args) {
61
61
  elementsData: [{
62
62
  name: args.elementName,
63
63
  type: args.elementType,
64
- locators: [{ xpath: args.selector }],
64
+ locators: [{ "name": "xpath", "value": args.selector }],
65
65
  platform: args.platform
66
66
  }]
67
67
  };
@@ -60,7 +60,7 @@ async function verifyPartialAttributeValue(args) {
60
60
  elementsData: [{
61
61
  name: args.elementName,
62
62
  type: args.elementType,
63
- locators: [{ xpath: args.selector }],
63
+ locators: [{ "name": "xpath", "value": args.selector }],
64
64
  platform: args.platform
65
65
  }]
66
66
  }));
@@ -21,7 +21,7 @@ async function checkIfElementIsDisplayed(args) {
21
21
  elementsData: [{
22
22
  name: args.elementName,
23
23
  type: args.elementType,
24
- locators: [{ xpath: args.selector }],
24
+ locators: [{ "name": "xpath", "value": args.selector }],
25
25
  platform: args.platform
26
26
  }]
27
27
  }));
@@ -17,7 +17,7 @@ const MOB_WaitTillAttributeOfElementContainsString = async (args) => {
17
17
  elementsData: [{
18
18
  name: args.elementName,
19
19
  type: args.elementType,
20
- locators: [{ name: "xpath", value: args.selector }],
20
+ locators: [{ "name": "xpath", "value": args.selector }],
21
21
  platform: args.platform
22
22
  }]
23
23
  };
@@ -23,7 +23,7 @@ async function waitTillAttributeOfElementIsString(args) {
23
23
  elementsData: [{
24
24
  name: args.elementName,
25
25
  type: args.elementType,
26
- locators: [{ xpath: args.selector }],
26
+ locators: [{ "name": "xpath", "value": args.selector }],
27
27
  platform: args.platform
28
28
  }]
29
29
  };
@@ -20,7 +20,7 @@ async function waitTillElementContainsText(args) {
20
20
  elementsData: [{
21
21
  name: args.elementName,
22
22
  type: args.elementType,
23
- locators: [{ xpath: args.selector }],
23
+ locators: [{ "name": "xpath", "value": args.selector }],
24
24
  platform: args.platform
25
25
  }]
26
26
  };
@@ -17,7 +17,7 @@ async function waitTillElementHasText(args) {
17
17
  elementsData: [{
18
18
  name: args.elementName,
19
19
  type: args.elementType,
20
- locators: [{ xpath: args.selector }],
20
+ locators: [{ "name": "xpath", "value": args.selector }],
21
21
  platform: args.platform
22
22
  }]
23
23
  };
@@ -21,7 +21,7 @@ async function waitTillElementIsClickable(args) {
21
21
  elementsData: [{
22
22
  name: args.elementName,
23
23
  type: args.elementType,
24
- locators: [{ xpath: args.selector }],
24
+ locators: [{ "name": "xpath", "value": args.selector }],
25
25
  platform: args.platform
26
26
  }]
27
27
  };
@@ -43,7 +43,6 @@ class MobileSession {
43
43
  throw new Error("Appium server is not running or unreachable.", { cause: error });
44
44
  }
45
45
  try {
46
- logData_js_1.logger.info(this.adbPath);
47
46
  await (0, child_process_1.execSync)(`${this.adbPath} -s ${arg.capabilities["appium:udid"]} shell pm clear ${appPackage}`).toString();
48
47
  await (0, child_process_1.execSync)(`${this.adbPath} -s ${arg.capabilities["appium:udid"]} shell am start -n ${appPackage}/${appActivity}`).toString();
49
48
  }
@@ -60,7 +59,7 @@ class MobileSession {
60
59
  const startTime = Date.now();
61
60
  this.driver = this.isCloud
62
61
  ? await this.cloudSessionInstances.initialize() : await this.openApp({ capabilities: arg.capabilities });
63
- logData_js_1.logger.info(`Application started ',total time taken: ${Date.now() - startTime} ms`);
62
+ logData_js_1.logger.info(`Application started total time taken: ${Date.now() - startTime} ms`);
64
63
  }
65
64
  async close() {
66
65
  if (this.driver) {
@@ -21,7 +21,7 @@ export interface IPayload {
21
21
  userId: string;
22
22
  projectType: string;
23
23
  tokensConsumed?: number;
24
- errorInfo?: IErrorInfo;
24
+ error?: IErrorInfo;
25
25
  }
26
26
  export interface IFireFlinkApiService {
27
27
  getInstancesDetailsApi(headers: Record<string, string>, url: string): Promise<any>;
@@ -50,11 +50,11 @@ function createActionHandlers(context) {
50
50
  "appium:ignoreUnimportantViews": false,
51
51
  "appium:disableAndroidWatcher": true,
52
52
  "appium:disableWindowAnimation": true,
53
- "appium:uiautomator2ServerLaunchTimeout": 60000,
54
- "appium:uiautomator2ServerReadTimeout": 60000,
55
- "appium:waitForIdleTimeout": 60000,
56
- "appium:waitForIdlePollingInterval": 60000,
57
- "appium:waitForSelectorTimeout": 60000,
53
+ "appium:uiautomator2ServerLaunchTimeout": 5000,
54
+ "appium:uiautomator2ServerReadTimeout": 5000,
55
+ "appium:waitForIdleTimeout": 5000,
56
+ "appium:waitForIdlePollingInterval": 5000,
57
+ "appium:waitForSelectorTimeout": 5000,
58
58
  },
59
59
  keywords: result.keywords
60
60
  });
@@ -529,11 +529,18 @@ class AutomationRunner {
529
529
  }
530
530
  catch (error) {
531
531
  logData_js_1.logger.error(`Error executing step "${step}":`, error);
532
- errorInfo = (await stepProcessor.getLLMResponse({ platform: platform, type: promptType_js_1.PromptType.ERROR_DESCRIPTION, args: {}, input: { error: logData_js_1.logger.getError(error) } })).response;
533
- if (errorInfo.error === "Context Length Exceeded (400)" ||
534
- errorInfo.error === "Rate Limit Exceeded (429)") {
532
+ if (error.error === "Context Length Exceeded (400)" ||
533
+ error.error === "Rate Limit Exceeded (429)") {
534
+ errorInfo.error = error.error;
535
+ errorInfo.errorDescription = error.errorDescription;
536
+ if (context.scriptAppender.getErrorNLP()) {
537
+ errorInfo.nlp = context.scriptAppender.getErrorNLP();
538
+ }
539
+ errorInfo.erroredManualStep = step;
540
+ errorInfo.rawError = logData_js_1.logger.getError(error);
535
541
  break;
536
542
  }
543
+ errorInfo = (await stepProcessor.getLLMResponse({ platform: platform, type: promptType_js_1.PromptType.ERROR_DESCRIPTION, args: {}, input: { error: logData_js_1.logger.getError(error) } })).response;
537
544
  if (context.scriptAppender.getErrorNLP()) {
538
545
  errorInfo.nlp = context.scriptAppender.getErrorNLP();
539
546
  }
@@ -559,7 +566,9 @@ class AutomationRunner {
559
566
  userId: request.userId,
560
567
  projectType: request.projectType,
561
568
  tokensConsumed: (await stepProcessor.getResultTokenUsage()).totalTokens,
562
- ...(errorInfo && Object.keys(errorInfo).length > 0 && { errorInfo })
569
+ ...(errorInfo && Object.keys(errorInfo).length > 0
570
+ ? { error: errorInfo }
571
+ : {})
563
572
  };
564
573
  try {
565
574
  await context.scriptAppender.waitForAllSteps();
@@ -22,7 +22,7 @@ exports.sameActionHelper = {
22
22
  MOB_GetDriverInstance: "GetDriverInstance",
23
23
  MOB_GetCurrentWindowHandle: "GetCurrentWindowHandle",
24
24
  MOB_GetTagName: "GetTagName",
25
- MOB_GetScreenshotAs: "GetScreenshotAs",
25
+ MOB_GetScreenshotOfElement: "GetScreenshotAs",
26
26
  MOB_GetX: "GetXLocationOfWebElement",
27
27
  MOB_GetLocation: "GetLocation",
28
28
  MOB_GetY: "GetYLocationOfWebElement",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ff-automationv2",
3
- "version": "2.2.26",
3
+ "version": "2.2.27",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "description": "This lib is used to automate the manual testcase",