ff-automationv2 2.2.31 → 2.2.32-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/llmprompts/llmPromptTypes/systemPromptTypes.d.ts +3 -0
- package/dist/ai/llmprompts/promptRegistry.js +10 -2
- package/dist/ai/llmprompts/systemPrompts/actionExtractorPrompt.js +83 -27
- package/dist/ai/llmprompts/systemPrompts/fileVerifyActionExtractorPrompt.d.ts +2 -0
- package/dist/ai/llmprompts/systemPrompts/fileVerifyActionExtractorPrompt.js +35 -0
- package/dist/ai/llmprompts/systemPrompts/fireflinkElementIndexExtactors.js +35 -0
- package/dist/ai/llmprompts/systemPrompts/fireflinkElementIndexExtractor_Mob.js +5 -2
- package/dist/ai/llmprompts/systemPrompts/getActionExtractorPrompt.js +4 -2
- package/dist/ai/llmprompts/systemPrompts/getActionExtractorPromptMob.js +3 -1
- package/dist/ai/llmprompts/systemPrompts/inputContextPrompt.d.ts +2 -0
- package/dist/ai/llmprompts/systemPrompts/inputContextPrompt.js +54 -0
- package/dist/ai/llmprompts/systemPrompts/mobileKeywordExtractor.js +53 -8
- package/dist/ai/llmprompts/systemPrompts/verifyActionExtractorPrompt.js +5 -4
- package/dist/ai/llmprompts/systemPrompts/verifyActionExtractorPromptMob.js +1 -1
- package/dist/ai/llmprompts/userPrompts/userPrompt.js +2 -0
- package/dist/automation/actions/executor.d.ts +14 -6
- package/dist/automation/actions/executor.js +968 -251
- package/dist/automation/actions/interaction/alert/enterDataToAlert.js +3 -1
- package/dist/automation/actions/interaction/alert/getTextPresentOnAlertPopup.js +4 -0
- package/dist/automation/actions/interaction/alert/verifyAlertPopUpMessageContainsString.js +1 -1
- package/dist/automation/actions/interaction/alert/verifyAlertPopupIsDisplayed.js +1 -1
- package/dist/automation/actions/interaction/alert/verifyTextPresentOnAlertPopup.js +1 -1
- package/dist/automation/actions/interaction/clear/clearAndEnter.js +6 -3
- package/dist/automation/actions/interaction/elementlessActions/getOtp.js +25 -24
- package/dist/automation/actions/interaction/enterActions/EnterInputIntoElementFromClipBoardInterface_mob.js +3 -1
- package/dist/automation/actions/interaction/enterActions/enterInput.js +5 -2
- package/dist/automation/actions/interaction/enterActions/enterInputAndPress.js +5 -2
- package/dist/automation/actions/interaction/enterActions/enterUrl.js +5 -2
- package/dist/automation/actions/interaction/enterActions/enterusingJs.js +3 -1
- package/dist/automation/actions/interaction/enterActions/waitAndEnter.js +5 -2
- package/dist/automation/actions/interaction/files/VerifyPDF.d.ts +2 -0
- package/dist/automation/actions/interaction/files/VerifyPDF.js +171 -0
- package/dist/automation/actions/interaction/get/MOB_GetADBLogsForGivenAppPackage.js +4 -1
- package/dist/automation/actions/interaction/get/MOB_GetAllContexts.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetAllWindowHandles.d.ts +1 -1
- package/dist/automation/actions/interaction/get/MOB_GetAllWindowHandles.js +10 -6
- package/dist/automation/actions/interaction/get/MOB_GetAltitude.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetBatteryPercentage.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetBatteryStatus.d.ts +1 -1
- package/dist/automation/actions/interaction/get/MOB_GetBatteryStatus.js +7 -3
- package/dist/automation/actions/interaction/get/MOB_GetClipBoardText.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetCurrentActivity.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetCurrentAppPackage.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetCurrentContext.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetCurrentDeviceDate.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetCurrentDeviceSettings.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetCurrentDeviceStatus.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetCurrentDeviceSystemBars.js +5 -2
- package/dist/automation/actions/interaction/get/MOB_GetCurrentDeviceTime.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetCurrentOrientation.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetCurrentSessionId.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetDeviceLocation.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetDeviceName.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetDeviceOsVersion.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetDeviceUdid.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetHeightOfElement.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetHeightOfScreen.js +4 -0
- package/dist/automation/actions/interaction/get/MOB_GetHourFromCurrentDeviceTime.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetLatitude.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetLongitude.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetMinuteFromCurrentDeviceTime.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetSecondFromCurrentDeviceTime.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetSizeOfScreen.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetSupportedPerformanceDataTypes.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetTextFromElementAndSetToClipBoard.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetWidthOfElement.js +5 -1
- package/dist/automation/actions/interaction/get/MOB_GetWidthOfScreen.js +5 -1
- package/dist/automation/actions/interaction/get/browserWindowGetPosition.js +5 -0
- package/dist/automation/actions/interaction/get/getAllBrokenImages.js +9 -0
- package/dist/automation/actions/interaction/get/getAllBrokenLinkCount.js +9 -0
- package/dist/automation/actions/interaction/get/getAllBrokenLinks.js +10 -1
- package/dist/automation/actions/interaction/get/getAllConsoleErrors.js +11 -0
- package/dist/automation/actions/interaction/get/getAllConsoleInformation.js +12 -1
- package/dist/automation/actions/interaction/get/getAllConsoleLogs.js +11 -1
- package/dist/automation/actions/interaction/get/getAllConsoleWarnings.js +12 -1
- package/dist/automation/actions/interaction/get/getAllCookieNames.js +6 -1
- package/dist/automation/actions/interaction/get/getAllCookieValues.js +6 -1
- package/dist/automation/actions/interaction/get/getAllSelectedOptions.js +8 -1
- package/dist/automation/actions/interaction/get/getAllTheOptionsFromListBoxAsText.js +4 -1
- package/dist/automation/actions/interaction/get/getAllTheOptionsFromListBoxAsTextInSortedOrder.js +4 -1
- package/dist/automation/actions/interaction/get/getAllTheSelectedOptionsFromListBoxAsText.js +4 -1
- package/dist/automation/actions/interaction/get/getAllWindowHandles.js +5 -1
- package/dist/automation/actions/interaction/get/getAttribute.js +19 -14
- package/dist/automation/actions/interaction/get/getAudioCurrentPlaybackRate.js +4 -1
- package/dist/automation/actions/interaction/get/getAudioCurrentSeekTime.js +4 -1
- package/dist/automation/actions/interaction/get/getAudioCurrentVolume.js +4 -1
- package/dist/automation/actions/interaction/get/getAudioDecodedByte.js +4 -1
- package/dist/automation/actions/interaction/get/getAudioDefaultPlaybackRate.js +4 -1
- package/dist/automation/actions/interaction/get/getAudioMediaLength.js +4 -1
- package/dist/automation/actions/interaction/get/getAudioMediaSource.js +4 -1
- package/dist/automation/actions/interaction/get/getBestPracticesScore.js +11 -3
- package/dist/automation/actions/interaction/get/getBrowserCount.js +5 -0
- package/dist/automation/actions/interaction/get/getBrowserVersion.js +5 -0
- package/dist/automation/actions/interaction/get/getCapabilityNames.js +5 -0
- package/dist/automation/actions/interaction/get/getClipBoardText.js +13 -0
- package/dist/automation/actions/interaction/get/getCollectiveApiResponseTime.js +4 -1
- package/dist/automation/actions/interaction/get/getCollectiveApiStatusCode.js +4 -1
- package/dist/automation/actions/interaction/get/getCssValue.js +5 -1
- package/dist/automation/actions/interaction/get/getCurrentDayOfTheWeek.js +4 -0
- package/dist/automation/actions/interaction/get/getCurrentSecondsFromCurrentSystemTime.js +5 -1
- package/dist/automation/actions/interaction/get/getCurrentSystemDate.js +4 -0
- package/dist/automation/actions/interaction/get/getCurrentSystemDay.js +5 -1
- package/dist/automation/actions/interaction/get/getCurrentSystemMonth.js +5 -1
- package/dist/automation/actions/interaction/get/getCurrentSystemTime.js +5 -1
- package/dist/automation/actions/interaction/get/getCurrentSystemYear.js +5 -1
- package/dist/automation/actions/interaction/get/getCurrentWindowHandle.js +13 -26
- package/dist/automation/actions/interaction/get/getDataFromApiRequestHeaderForJsonPath.js +5 -4
- package/dist/automation/actions/interaction/get/getDataFromApiResponseForJsonPath.js +5 -4
- package/dist/automation/actions/interaction/get/getDateWithGivenFormat.js +13 -16
- package/dist/automation/actions/interaction/get/getDriverInstance.js +13 -28
- package/dist/automation/actions/interaction/get/getFirstContentfulPaint.js +8 -1
- package/dist/automation/actions/interaction/get/getFirstSelectedOption.js +5 -1
- package/dist/automation/actions/interaction/get/getFullPaintTime.js +8 -1
- package/dist/automation/actions/interaction/get/getHTMLCodeOfPage.js +4 -0
- package/dist/automation/actions/interaction/get/getHeightOfBrowserWindow.js +5 -0
- package/dist/automation/actions/interaction/get/getHeightOfWebElement.js +4 -1
- package/dist/automation/actions/interaction/get/getHourFromCurrentSystemTime.js +4 -0
- package/dist/automation/actions/interaction/get/getImplicitTimeOut.js +15 -28
- package/dist/automation/actions/interaction/get/getLargestContentfulPaint.js +7 -0
- package/dist/automation/actions/interaction/get/getListBoxSize.d.ts +1 -1
- package/dist/automation/actions/interaction/get/getListBoxSize.js +4 -2
- package/dist/automation/actions/interaction/get/getListOfElementsFromLocatorTypeLocatorValue.js +7 -2
- package/dist/automation/actions/interaction/get/getLocation.js +14 -8
- package/dist/automation/actions/interaction/get/getMinuteFromCurrentSystemTime.js +4 -0
- package/dist/automation/actions/interaction/get/getNetworkRouteTime.js +7 -0
- package/dist/automation/actions/interaction/get/getNumberOfBrokenImages.js +7 -0
- package/dist/automation/actions/interaction/get/getNumberOfLinksPresentInCurrentPage.js +5 -0
- package/dist/automation/actions/interaction/get/getNumberOfWorkingLinksFromCurrentPage.js +9 -0
- package/dist/automation/actions/interaction/get/getOptions.js +4 -1
- package/dist/automation/actions/interaction/get/getPageTitle.js +5 -1
- package/dist/automation/actions/interaction/get/getPerformanceMetrics.js +12 -1
- package/dist/automation/actions/interaction/get/getPwaScore.js +11 -3
- package/dist/automation/actions/interaction/get/getRect.js +9 -2
- package/dist/automation/actions/interaction/get/getScreenshot.js +13 -28
- package/dist/automation/actions/interaction/get/getScreenshotAs.js +14 -44
- package/dist/automation/actions/interaction/get/getSeoScore.js +15 -3
- package/dist/automation/actions/interaction/get/getSingleApiRequestPayload.js +5 -3
- package/dist/automation/actions/interaction/get/getSingleApiResponse.js +9 -8
- package/dist/automation/actions/interaction/get/getSingleApiResponseTime.js +9 -9
- package/dist/automation/actions/interaction/get/getSingleApiStatusCode.d.ts +1 -1
- package/dist/automation/actions/interaction/get/getSingleApiStatusCode.js +10 -17
- package/dist/automation/actions/interaction/get/getSize.js +7 -2
- package/dist/automation/actions/interaction/get/getSizeOfBrowserWindow.js +5 -4
- package/dist/automation/actions/interaction/get/getStringDataFromLocalFile.js +10 -7
- package/dist/automation/actions/interaction/get/getSystemProperty.js +6 -4
- package/dist/automation/actions/interaction/get/getTagName.js +9 -2
- package/dist/automation/actions/interaction/get/getText.js +7 -2
- package/dist/automation/actions/interaction/get/getTheFirstSelectedOptionFromListBoxAsText.js +5 -1
- package/dist/automation/actions/interaction/get/getTotalNumberOfCookies.js +6 -1
- package/dist/automation/actions/interaction/get/getTunnelIdentifier.js +5 -8
- package/dist/automation/actions/interaction/get/getURLPresentInAddressBar.js +5 -1
- package/dist/automation/actions/interaction/get/getUserHomeDirectory.js +9 -1
- package/dist/automation/actions/interaction/get/getValueByCookieName.js +7 -4
- package/dist/automation/actions/interaction/get/getValueFromLocalStorage.js +6 -4
- package/dist/automation/actions/interaction/get/getValueOfSystemVariable.js +6 -4
- package/dist/automation/actions/interaction/get/getVideoCurrentPlaybackRate.js +4 -1
- package/dist/automation/actions/interaction/get/getVideoCurrentSeekTime.js +4 -1
- package/dist/automation/actions/interaction/get/getVideoCurrentVolume.js +4 -1
- package/dist/automation/actions/interaction/get/getVideoDecodedByte.js +4 -1
- package/dist/automation/actions/interaction/get/getVideoDefaultPlaybackRate.js +4 -1
- package/dist/automation/actions/interaction/get/getVideoMediaLength.js +4 -1
- package/dist/automation/actions/interaction/get/getVideoMediaSource.js +5 -1
- package/dist/automation/actions/interaction/get/getWidthOfBrowser.js +6 -1
- package/dist/automation/actions/interaction/get/getWidthOfWebElement.js +4 -1
- package/dist/automation/actions/interaction/get/getWorkingLinksFromCurrentPage.js +10 -1
- package/dist/automation/actions/interaction/get/getWrappedElement.js +5 -1
- package/dist/automation/actions/interaction/get/getWrappedOptionFromListBoxAsText.d.ts +1 -1
- package/dist/automation/actions/interaction/get/getWrappedOptionFromListBoxAsText.js +4 -2
- package/dist/automation/actions/interaction/get/getXLocationOfBrowserWindow.js +4 -3
- package/dist/automation/actions/interaction/get/getXLocationOfWebElement.js +7 -2
- package/dist/automation/actions/interaction/get/getYLocationOfBrowserWindow.js +6 -1
- package/dist/automation/actions/interaction/get/getYLocationOfWebElement.js +7 -2
- package/dist/automation/actions/interaction/shadowDom/shadowDomEnter.js +2 -0
- package/dist/automation/actions/interaction/shadowDom/shadowDomGetText.js +5 -2
- package/dist/automation/actions/interaction/verify/MOB_VerifyBatteryLevel.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyAttributeValue.js +2 -2
- package/dist/automation/actions/interaction/verify/VerifyBrowserHtmlCodeContainsString.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyBrowserWindowHeight.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyBrowserWindowTitleContainsString.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyBrowserWindowTitleIsString.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyBrowserWindowUrlContainsExpectedUrl.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyBrowserWindowUrlIsString.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyBrowserWindowWidth.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyBrowserWindowXLocation.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyBrowserWindowYLocation.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyCssAttributeValue.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyElementNotContainsText.js +2 -2
- package/dist/automation/actions/interaction/verify/VerifyHeightOfWebElement.js +2 -2
- package/dist/automation/actions/interaction/verify/VerifyHexCodeForGivenXYCoordinates.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfAllCookiesAreDeleted.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfCookieNameIsAdded.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfCookieNameIsDeleted.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfCookieObjectIsPresent.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfGivenOptionIsDuplicate.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfImageIsBroken.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfLinkIsBroken.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfLinkIsWorking.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfLinksAreBroken.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfLinksAreWorking.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfOptionWithTextIsDeselected.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfOptionWithValueIsDeselected.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfOptionWithValueIsSelected.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfOptionWithVisibleTextIsSelected.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyIfSpecifiedOptionIsSelected.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyNavigateURL.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyPartialAttributeValue.js +2 -2
- package/dist/automation/actions/interaction/verify/VerifyPartialTitleOfCurrentPage.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyTagName.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyThatSpecifiedOptionIsNotSelected.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyTitleInAllPage.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyTitleOfCurrentPage.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyValueOfElementContainsString.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyValueOfElementIsString.js +1 -1
- package/dist/automation/actions/interaction/verify/VerifyWidthOfElement.js +2 -2
- package/dist/automation/actions/interaction/verify/VerifyXLocationOfElement.js +2 -2
- package/dist/automation/actions/interaction/verify/VerifyYLocationOfElement.js +2 -2
- package/dist/automation/actions/interaction/verify/checkIfElementIsDisplayed.js +2 -2
- package/dist/automation/actions/interaction/verify/verifypartialtext.js +2 -2
- package/dist/automation/actions/interaction/verify/verifytext.js +2 -2
- package/dist/automation/actions/interface/FireFlinkResponseSchema.d.ts +22 -1
- package/dist/automation/actions/interface/FireFlinkResponseSchema.js +18 -4
- package/dist/automation/actions/interface/alertActionInterface.d.ts +11 -0
- package/dist/automation/actions/interface/clearActionInterface.d.ts +4 -0
- package/dist/automation/actions/interface/getActionInterface.d.ts +150 -141
- package/dist/automation/actions/interface/getOtpInterface.d.ts +5 -0
- package/dist/automation/actions/interface/interactionActionInterface.d.ts +14 -7
- package/dist/automation/actions/interface/shadowDomInterface.d.ts +10 -0
- package/dist/automation/actions/interface/verifyActionInterface.d.ts +100 -0
- package/dist/core/Errors/InvalidFileTypeError.d.ts +5 -0
- package/dist/core/Errors/InvalidFileTypeError.js +14 -0
- package/dist/core/constants/supportedActions.js +4 -0
- package/dist/core/helpers/elementSelectorResolver.d.ts +11 -0
- package/dist/core/helpers/elementSelectorResolver.js +102 -0
- package/dist/core/helpers/runnerDomPipeline.d.ts +9 -0
- package/dist/core/helpers/runnerDomPipeline.js +97 -0
- package/dist/core/helpers/runnerKafkaReporter.d.ts +17 -0
- package/dist/core/helpers/runnerKafkaReporter.js +71 -0
- package/dist/core/helpers/runnerPostActionHelper.d.ts +2 -0
- package/dist/core/helpers/runnerPostActionHelper.js +30 -0
- package/dist/core/helpers/stepActionInspector.d.ts +5 -0
- package/dist/core/helpers/stepActionInspector.js +113 -0
- package/dist/core/helpers/visionFallbackHandler.d.ts +3 -0
- package/dist/core/helpers/visionFallbackHandler.js +138 -0
- package/dist/core/interfaces/actionInterface.d.ts +7 -5
- package/dist/core/interfaces/automationRunnerInterface.d.ts +56 -1
- package/dist/core/interfaces/fireflinkScriptPayloadInterface.d.ts +2 -0
- package/dist/core/interfaces/llmResponseInterface.d.ts +5 -0
- package/dist/core/interfaces/promptInterface.d.ts +9 -2
- package/dist/core/interfaces/scriptGenrationDataInterface.d.ts +4 -0
- package/dist/core/main/actionHandlerFactory.js +37 -7
- package/dist/core/main/executionContext.d.ts +2 -1
- package/dist/core/main/executionContext.js +3 -2
- package/dist/core/main/runAutomationScript.d.ts +1 -0
- package/dist/core/main/runAutomationScript.js +390 -1008
- package/dist/core/types/llmResponseType.d.ts +2 -2
- package/dist/core/types/promptType.d.ts +3 -1
- package/dist/core/types/promptType.js +2 -0
- package/dist/fireflinkData/fireflinkScript/appendScriptData.js +3 -0
- package/dist/utils/browserCap/capability.js +17 -0
- package/dist/utils/helpers/getHelper.d.ts +8 -0
- package/dist/utils/helpers/getHelper.js +115 -0
- package/dist/utils/helpers/platformSyntax.d.ts +1 -1
- package/package.json +2 -1
- package/dist/ai/llmprompts/systemPrompts/combinedActionExtractorPrompt.d.ts +0 -2
- package/dist/ai/llmprompts/systemPrompts/combinedActionExtractorPrompt.js +0 -36
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.AutomationRunner = void 0;
|
|
4
7
|
require("../../utils/sslConfig/apiCallPatch.js");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
5
10
|
const platformContext_js_1 = require("../../utils/helpers/platformContext.js");
|
|
6
11
|
const llmConfiguration_js_1 = require("../../llmConfig/llmConfiguration.js");
|
|
7
12
|
const llmAction_js_1 = require("../../ai/llmcalls/llmAction.js");
|
|
@@ -12,27 +17,22 @@ const fireflink_service_js_1 = require("../../service/fireflink.service.js");
|
|
|
12
17
|
const promptType_js_1 = require("../types/promptType.js");
|
|
13
18
|
const supportedActions_js_1 = require("../constants/supportedActions.js");
|
|
14
19
|
const getRelaventElements_js_1 = require("../../domAnalysis/getRelaventElements.js");
|
|
15
|
-
const jsForAttributeInjection_js_1 = require("../../utils/DomExtraction/jsForAttributeInjection.js");
|
|
16
|
-
const jsdom_1 = require("jsdom");
|
|
17
|
-
const jsForAttributeInjection_js_2 = require("../../utils/DomExtraction/jsForAttributeInjection.js");
|
|
18
20
|
const allAction_js_1 = require("../constants/allAction.js");
|
|
19
21
|
const newTabTracker_js_1 = require("../../utils/newTab/newTabTracker.js");
|
|
20
|
-
const generateAnnotatedScreenshots_js_1 = require("../../imageAnalysisWeb/generateAnnotatedScreenshots.js");
|
|
21
22
|
const getInstancesInfo_js_1 = require("../../utils/InstancesDetails/getInstancesInfo.js");
|
|
22
23
|
const isAlertPresent_js_1 = require("../../utils/alertPopup/isAlertPresent.js");
|
|
23
|
-
const jsForToaster_js_1 = require("../../utils/javascript/jsForToaster.js");
|
|
24
|
-
const jsFindElement_js_1 = require("../../utils/javascript/jsFindElement.js");
|
|
25
|
-
const xpathcreation_js_1 = require("../../utils/helpers/xpathcreation.js");
|
|
26
24
|
const logData_js_1 = require("../../utils/logger/logData.js");
|
|
27
25
|
const sameActionsHelper_js_1 = require("../../utils/helpers/sameActionsHelper.js");
|
|
28
|
-
const node_console_1 = require("node:console");
|
|
29
|
-
const annotatedScreenshotMobile_js_1 = require("../../imageAnalysisMobile/annotatedScreenshotMobile.js");
|
|
30
|
-
const toon_1 = require("@toon-format/toon");
|
|
31
26
|
const messageType_js_1 = require("../types/messageType.js");
|
|
32
27
|
const platformSyntax_js_1 = require("../../utils/helpers/platformSyntax.js");
|
|
33
28
|
const driverState_js_1 = require("../../automation/driverState.js");
|
|
34
29
|
const SessionManager_js_1 = require("./SessionManager.js");
|
|
35
|
-
const
|
|
30
|
+
const runnerKafkaReporter_js_1 = require("../helpers/runnerKafkaReporter.js");
|
|
31
|
+
const runnerDomPipeline_js_1 = require("../helpers/runnerDomPipeline.js");
|
|
32
|
+
const stepActionInspector_js_1 = require("../helpers/stepActionInspector.js");
|
|
33
|
+
const elementSelectorResolver_js_1 = require("../helpers/elementSelectorResolver.js");
|
|
34
|
+
const runnerPostActionHelper_js_1 = require("../helpers/runnerPostActionHelper.js");
|
|
35
|
+
const visionFallbackHandler_js_1 = require("../helpers/visionFallbackHandler.js");
|
|
36
36
|
class AutomationRunner {
|
|
37
37
|
constructor() {
|
|
38
38
|
this.KafkaPayload = {};
|
|
@@ -66,11 +66,12 @@ class AutomationRunner {
|
|
|
66
66
|
}
|
|
67
67
|
return "Web";
|
|
68
68
|
}
|
|
69
|
-
async cleanup(context, domInfo, extractedRelevantDom, stepProcessor,
|
|
69
|
+
async cleanup(context, domInfo, extractedRelevantDom, stepProcessor, stepsInputData, fireflinkServiceInstance, request, currentPlatform) {
|
|
70
70
|
try {
|
|
71
71
|
logData_js_1.logger.info("Starting cleanup process...");
|
|
72
72
|
domInfo = null;
|
|
73
73
|
extractedRelevantDom = null;
|
|
74
|
+
stepsInputData.length = 0;
|
|
74
75
|
try {
|
|
75
76
|
if (context?.session) {
|
|
76
77
|
const webDriver = await context.session.getCurrentDriver().catch(() => null);
|
|
@@ -92,7 +93,7 @@ class AutomationRunner {
|
|
|
92
93
|
if (context?.mobileSession) {
|
|
93
94
|
const mobileDriver = await context.mobileSession.getCurrentDriver().catch(() => null);
|
|
94
95
|
if (mobileDriver?.sessionId) {
|
|
95
|
-
if (
|
|
96
|
+
if (currentPlatform === "ios") {
|
|
96
97
|
logData_js_1.logger.info("iOS session is not deleted");
|
|
97
98
|
}
|
|
98
99
|
else {
|
|
@@ -108,8 +109,18 @@ class AutomationRunner {
|
|
|
108
109
|
if (stepProcessor) {
|
|
109
110
|
stepProcessor.llm = null;
|
|
110
111
|
}
|
|
111
|
-
|
|
112
|
+
fireflinkServiceInstance = null;
|
|
112
113
|
delete AutomationRunner.sessionTerminationDetails[request.testCaseId];
|
|
114
|
+
try {
|
|
115
|
+
const tempFileDir = path_1.default.resolve(process.cwd(), "session", "temp_file");
|
|
116
|
+
if (fs_1.default.existsSync(tempFileDir)) {
|
|
117
|
+
fs_1.default.rmSync(tempFileDir, { recursive: true, force: true });
|
|
118
|
+
logData_js_1.logger.info(`Cleaned up temp_file directory: ${tempFileDir}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
logData_js_1.logger.error("Error cleaning up temp_file directory:", err);
|
|
123
|
+
}
|
|
113
124
|
if (global.gc) {
|
|
114
125
|
global.gc();
|
|
115
126
|
}
|
|
@@ -119,17 +130,31 @@ class AutomationRunner {
|
|
|
119
130
|
logData_js_1.logger.error("Cleanup error:", error);
|
|
120
131
|
}
|
|
121
132
|
}
|
|
133
|
+
async saveSessionStepData(context, kafkaMessageKey) {
|
|
134
|
+
await context.scriptAppender.waitForAllSteps();
|
|
135
|
+
if (driverState_js_1.UserSessionAutomationTestCase[kafkaMessageKey]) {
|
|
136
|
+
driverState_js_1.UserSessionAutomationTestCase[kafkaMessageKey].push(...context.scriptAppender.getData());
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
driverState_js_1.UserSessionAutomationTestCase[kafkaMessageKey] = context.scriptAppender.getData();
|
|
140
|
+
}
|
|
141
|
+
context.scriptAppender.reset();
|
|
142
|
+
}
|
|
122
143
|
async run(request) {
|
|
123
144
|
const usedElementNames = [];
|
|
145
|
+
const usedVariableNames = [];
|
|
124
146
|
(0, logData_js_1.initLogger)(request.sessionPath);
|
|
125
147
|
request.type = request.platform;
|
|
126
148
|
request.platform = AutomationRunner.normalizeScriptType(request.platform);
|
|
149
|
+
const isWebMobile = request.type?.toLowerCase().includes("web") &&
|
|
150
|
+
request.type?.toLowerCase().includes("android");
|
|
127
151
|
logData_js_1.logger.info("User Given Step", request.userStory);
|
|
128
152
|
const data = JSON.parse(request.scriptName);
|
|
129
153
|
const hasMoreSteps = data.hasMoreSteps;
|
|
130
154
|
request.scriptName = data.automationScriptName;
|
|
131
|
-
if (request.isTerminate)
|
|
155
|
+
if (request.isTerminate) {
|
|
132
156
|
return AutomationRunner.updateSessionTerminationInfo(request.testCaseId);
|
|
157
|
+
}
|
|
133
158
|
AutomationRunner.sessionTerminationDetails[request.testCaseId] = request.isTerminate;
|
|
134
159
|
const apiService = new fireflinkApi_service_js_1.FireFlinkApiService();
|
|
135
160
|
const fireflinkServiceInstance = new fireflink_service_js_1.fireflinkService(apiService, request.broker, request.sslConfig);
|
|
@@ -147,926 +172,433 @@ class AutomationRunner {
|
|
|
147
172
|
const llm = new llmAction_js_1.llmAction(aiInfo.apiKey, provider, aiInfo.model, aiInfo.visionApiKey, aiInfo.accountType, aiInfo.enterpriseConfigFile, aiInfo.serviceProvider);
|
|
148
173
|
let preCapturedDomInfo = null;
|
|
149
174
|
const stepProcessor = new stepProcessor_js_1.StepProcessor(llm);
|
|
150
|
-
let
|
|
151
|
-
(0, platformContext_js_1.setPlatform)(
|
|
175
|
+
let currentPlatform = context.activePlatform;
|
|
176
|
+
(0, platformContext_js_1.setPlatform)(currentPlatform);
|
|
152
177
|
const actionHandlers = (0, actionHandlerFactory_js_1.createActionHandlers)(context);
|
|
153
178
|
const domProcessor = new getRelaventElements_js_1.DomProcessingEngine();
|
|
154
179
|
let stepCount = 1;
|
|
155
|
-
const
|
|
180
|
+
const stepsInputData = context.stepsInputData || (context.stepsInputData = []);
|
|
181
|
+
const listOfSteps = request.userStory.map((step) => String(step));
|
|
156
182
|
let driver;
|
|
157
|
-
if (listOfSteps.length
|
|
183
|
+
if (listOfSteps.length === 0 && request?.aiExecutionAction !== "stopExecution") {
|
|
158
184
|
logData_js_1.logger.info(listOfSteps);
|
|
159
185
|
throw new Error("No executable manual steps were returned by the LLM.");
|
|
160
186
|
}
|
|
161
187
|
if (aiInfo.serviceProvider === "DefaultFireFlink") {
|
|
162
|
-
logData_js_1.logger.info(
|
|
188
|
+
logData_js_1.logger.info("Service Provider --> DefaultFireFlink");
|
|
163
189
|
}
|
|
164
190
|
else {
|
|
165
191
|
logData_js_1.logger.info(`Service Provider --> ${aiInfo.serviceProvider} and Model --> ${aiInfo.model}`);
|
|
166
192
|
}
|
|
167
|
-
const
|
|
193
|
+
const reporter = new runnerKafkaReporter_js_1.RunnerKafkaReporter(fireflinkServiceInstance, request);
|
|
194
|
+
const startTime = new Date().getTime();
|
|
168
195
|
for (const [index, step] of listOfSteps.entries()) {
|
|
169
|
-
|
|
170
|
-
(0, platformContext_js_1.setPlatform)(
|
|
196
|
+
currentPlatform = context.activePlatform;
|
|
197
|
+
(0, platformContext_js_1.setPlatform)(currentPlatform);
|
|
171
198
|
let stepResult;
|
|
172
|
-
let stepResultVision;
|
|
173
199
|
let stepAction;
|
|
174
200
|
let fireflinkIndex;
|
|
175
201
|
let selector;
|
|
176
|
-
let xpath;
|
|
177
|
-
let frameAction;
|
|
178
|
-
let iframeDomHtml = null;
|
|
179
202
|
let doc;
|
|
180
203
|
let pageDOM;
|
|
181
204
|
let beforeHandles = null;
|
|
182
205
|
let baseStepActionBeforeFallback;
|
|
183
|
-
|
|
184
|
-
const produceLiveLog = async (message) => {
|
|
185
|
-
await fireflinkServiceInstance.produceMessageToKafka(request.kafkaMessageKey, {
|
|
186
|
-
topic: topic, message: {
|
|
187
|
-
topic: "",
|
|
188
|
-
service: "",
|
|
189
|
-
chatId: "",
|
|
190
|
-
aiPromptPayload: {
|
|
191
|
-
display: false,
|
|
192
|
-
message: "",
|
|
193
|
-
messageId: "",
|
|
194
|
-
branchId: "",
|
|
195
|
-
userId: request.userId,
|
|
196
|
-
scriptId: "",
|
|
197
|
-
scriptType: "",
|
|
198
|
-
type: "logs",
|
|
199
|
-
sessionId: "",
|
|
200
|
-
licenseId: request.licenseId,
|
|
201
|
-
projectId: request.projectId,
|
|
202
|
-
liveLogs: {
|
|
203
|
-
executionId: request.kafkaMessageKey,
|
|
204
|
-
message,
|
|
205
|
-
messageType: messageType_js_1.MessageType.LiveLog.retry,
|
|
206
|
-
},
|
|
207
|
-
attachment: [],
|
|
208
|
-
},
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
};
|
|
206
|
+
let inputValue;
|
|
212
207
|
try {
|
|
213
208
|
if (request?.aiExecutionAction === "stopExecution") {
|
|
214
209
|
break;
|
|
215
210
|
}
|
|
216
211
|
if (AutomationRunner.getSessionTerminationInfo(request.testCaseId)) {
|
|
217
|
-
|
|
218
|
-
await fireflinkServiceInstance.produceMessageToKafka(request.kafkaMessageKey, {
|
|
219
|
-
topic: topic, message: {
|
|
220
|
-
topic: "",
|
|
221
|
-
service: "",
|
|
222
|
-
chatId: "",
|
|
223
|
-
aiPromptPayload: {
|
|
224
|
-
display: false,
|
|
225
|
-
message: "",
|
|
226
|
-
messageId: "",
|
|
227
|
-
branchId: "",
|
|
228
|
-
userId: request.userId,
|
|
229
|
-
scriptId: "",
|
|
230
|
-
scriptType: "",
|
|
231
|
-
type: "logs",
|
|
232
|
-
sessionId: "",
|
|
233
|
-
licenseId: request.licenseId,
|
|
234
|
-
projectId: request.projectId,
|
|
235
|
-
liveLogs: {
|
|
236
|
-
executionId: request.kafkaMessageKey,
|
|
237
|
-
message: "Execution terminated by the user",
|
|
238
|
-
messageType: messageType_js_1.MessageType.LiveLog.Termination,
|
|
239
|
-
},
|
|
240
|
-
attachment: [],
|
|
241
|
-
},
|
|
242
|
-
}
|
|
243
|
-
});
|
|
212
|
+
await reporter.sendTermination();
|
|
244
213
|
break;
|
|
245
214
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const
|
|
215
|
+
const userStepIndex = index + 1;
|
|
216
|
+
logData_js_1.logger.info(`Processing step ${userStepIndex}: ${step}`);
|
|
217
|
+
const start = Math.max(0, index - 3);
|
|
218
|
+
const end = Math.min(listOfSteps.length, index + 4);
|
|
249
219
|
const priorAndNextSteps = listOfSteps.slice(start, end);
|
|
250
220
|
const result = await stepProcessor.getLLMResponse({
|
|
251
|
-
platform:
|
|
221
|
+
platform: currentPlatform,
|
|
252
222
|
type: promptType_js_1.PromptType.KEYWORD_EXTRACTOR,
|
|
253
223
|
args: { priorAndNextSteps },
|
|
254
|
-
input: { currentStep: step }
|
|
224
|
+
input: { currentStep: step },
|
|
255
225
|
});
|
|
256
|
-
if (
|
|
226
|
+
if (currentPlatform === "android" || currentPlatform === "ios") {
|
|
257
227
|
if (!driver) {
|
|
258
|
-
|
|
228
|
+
const initialKeywords = result.response?.keywords ||
|
|
229
|
+
(Array.isArray(result.response?.steps) ? result.response.steps[0]?.keywords : undefined);
|
|
230
|
+
await context.initializeMobileDriver(initialKeywords);
|
|
259
231
|
}
|
|
260
232
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
message: "",
|
|
269
|
-
messageId: "",
|
|
270
|
-
branchId: "",
|
|
271
|
-
userId: request.userId,
|
|
272
|
-
scriptId: "",
|
|
273
|
-
scriptType: "",
|
|
274
|
-
type: "logs",
|
|
275
|
-
sessionId: "",
|
|
276
|
-
licenseId: request.licenseId,
|
|
277
|
-
projectId: request.projectId,
|
|
278
|
-
liveLogs: {
|
|
279
|
-
executionId: request.kafkaMessageKey,
|
|
280
|
-
message: result.response.liveLog,
|
|
281
|
-
messageType: messageType_js_1.MessageType.LiveLog.Ongoing,
|
|
282
|
-
},
|
|
283
|
-
attachment: [],
|
|
284
|
-
},
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
logData_js_1.logger.info(`Message produced to Kafka topic - ${JSON.stringify({ messageType: messageType_js_1.MessageType.LiveLog.Ongoing })}`);
|
|
288
|
-
const action = result.response.action;
|
|
289
|
-
if (request.scenario && action === 'enter') {
|
|
290
|
-
const currentUserStoryStep = request.userStory[index];
|
|
291
|
-
if (currentUserStoryStep &&
|
|
292
|
-
currentUserStoryStep.length > 1 &&
|
|
293
|
-
typeof currentUserStoryStep[1] === 'string' &&
|
|
294
|
-
currentUserStoryStep[1].trim() == '') {
|
|
295
|
-
throw new Error(`Input is missing for the given step: ${currentUserStoryStep?.[0]}. Please provide the input.`);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
if (action === 'notwebopenaction') {
|
|
299
|
-
throw new Error(`Selected platform is invalid for the step: ${step}`);
|
|
300
|
-
}
|
|
301
|
-
if (!allAction_js_1.allKeywordAction.includes(action)) {
|
|
302
|
-
throw new Error(`Unsupported action at action or keyword exracter: ${action}`);
|
|
303
|
-
}
|
|
304
|
-
let handler = actionHandlers[action];
|
|
305
|
-
if (supportedActions_js_1.INPUTLESS_ACTIONS.includes(action)) {
|
|
306
|
-
logData_js_1.logger.info(result.response.keywords);
|
|
307
|
-
await handler({ keywords: result.response.keywords, step: step, driverSession: request.kafkaMessageKey });
|
|
308
|
-
stepCount++;
|
|
309
|
-
continue;
|
|
233
|
+
const stepsArray = Array.isArray(result.response?.steps)
|
|
234
|
+
? result.response.steps
|
|
235
|
+
: result.response?.action
|
|
236
|
+
? [result.response]
|
|
237
|
+
: null;
|
|
238
|
+
if (!stepsArray || stepsArray.length === 0) {
|
|
239
|
+
throw new Error(`No steps returned from action extractor for step: ${step}`);
|
|
310
240
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
241
|
+
const isOneToMany = stepsArray.length > 1;
|
|
242
|
+
for (let i = 0; i < stepsArray.length; i++) {
|
|
243
|
+
const stepObj = stepsArray[i];
|
|
244
|
+
const action = stepObj.action;
|
|
245
|
+
const keywords = stepObj.keywords;
|
|
246
|
+
const currentStep = action?.toLowerCase() === "getotp" ? step : stepObj.step || step;
|
|
247
|
+
let currentElementName = stepObj.elementName;
|
|
248
|
+
let currentVariableName;
|
|
249
|
+
let currentReturnTypeVariableName;
|
|
250
|
+
const liveLog = stepObj.liveLog;
|
|
251
|
+
const isStepValueDependable = stepObj.isStepValueDependable;
|
|
252
|
+
const currentStepIndex = isOneToMany ? `${userStepIndex}.${i + 1}` : userStepIndex;
|
|
253
|
+
logData_js_1.logger.info(isOneToMany
|
|
254
|
+
? `Sub-step ${currentStepIndex}: ${currentStep}`
|
|
255
|
+
: `Step ${currentStepIndex}: ${currentStep}`);
|
|
256
|
+
stepsInputData.currentManualStep = step;
|
|
257
|
+
stepsInputData.currentStepIndex = currentStepIndex;
|
|
258
|
+
context.executor?.setStepContext(currentStepIndex, currentStep, stepsInputData, step);
|
|
259
|
+
logData_js_1.logger.info("stepsInputData", stepsInputData);
|
|
260
|
+
const inputContextPromise = isStepValueDependable && stepsInputData.length > 0
|
|
261
|
+
? stepProcessor.getLLMResponse({
|
|
262
|
+
platform: currentPlatform,
|
|
263
|
+
type: promptType_js_1.PromptType.INPUT_CONTEXT_PROMPT,
|
|
264
|
+
args: { inputStepsContext: stepsInputData },
|
|
265
|
+
input: { currentStep },
|
|
266
|
+
})
|
|
267
|
+
: null;
|
|
268
|
+
await reporter.sendOngoing(liveLog);
|
|
269
|
+
if (request.scenario && action === "enter") {
|
|
270
|
+
const currentUserStoryStep = request.userStory[index];
|
|
271
|
+
if (currentUserStoryStep &&
|
|
272
|
+
currentUserStoryStep.length > 1 &&
|
|
273
|
+
typeof currentUserStoryStep[1] === "string" &&
|
|
274
|
+
currentUserStoryStep[1].trim() === "") {
|
|
275
|
+
throw new Error(`Input is missing for the given step: ${currentUserStoryStep?.[0]}. Please provide the input.`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (action === "notwebopenaction") {
|
|
279
|
+
throw new Error(`Selected platform is invalid for the step: ${step}`);
|
|
280
|
+
}
|
|
281
|
+
if (!allAction_js_1.allKeywordAction.includes(action)) {
|
|
282
|
+
throw new Error(`Unsupported action at action or keyword extractor: ${action}`);
|
|
283
|
+
}
|
|
284
|
+
let handler = actionHandlers[action];
|
|
285
|
+
if (supportedActions_js_1.INPUTLESS_ACTIONS.includes(action)) {
|
|
286
|
+
logData_js_1.logger.info(`Keywords ${JSON.stringify(keywords)}`);
|
|
287
|
+
await handler({ keywords, step: currentStep, driverSession: request.kafkaMessageKey });
|
|
288
|
+
stepCount++;
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if (action === "getOtp") {
|
|
292
|
+
if (!isWebMobile) {
|
|
293
|
+
throw new Error(`Selected platform is invalid for the step: ${step}`);
|
|
345
294
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
},
|
|
361
|
-
input: { currentStep: step }
|
|
362
|
-
});
|
|
363
|
-
const otpAction = platform === "android" || platform === "ios"
|
|
364
|
-
? sameActionsHelper_js_1.sameActionHelper[stepResult.response.nlpName] ||
|
|
365
|
-
stepResult.response.nlpName
|
|
366
|
-
: stepResult.response.nlpName;
|
|
367
|
-
handler = actionHandlers[otpAction];
|
|
368
|
-
await handler({
|
|
369
|
-
selector: stepResult.response.inputText,
|
|
370
|
-
timeFrom: stepResult.response.timeFrom,
|
|
371
|
-
waitTime: stepResult.response.waitTime,
|
|
372
|
-
activity: stepResult.response.activity,
|
|
373
|
-
otpExtractor: async (smsBody) => {
|
|
374
|
-
const llmRes = await stepProcessor.getLLMResponse({
|
|
375
|
-
platform: platform,
|
|
376
|
-
type: promptType_js_1.PromptType.OTP_EXTRACTOR,
|
|
377
|
-
args: {},
|
|
378
|
-
input: { smsBody }
|
|
379
|
-
});
|
|
380
|
-
if (llmRes.response?.otp) {
|
|
381
|
-
context.extractedOtp = llmRes.response.otp;
|
|
382
|
-
}
|
|
383
|
-
return llmRes.response;
|
|
295
|
+
stepResult = await stepProcessor.getLLMResponse({
|
|
296
|
+
platform: currentPlatform,
|
|
297
|
+
type: promptType_js_1.PromptType.FF_INSPECTOR,
|
|
298
|
+
args: {
|
|
299
|
+
stepAction: "getOtp",
|
|
300
|
+
extractedDomJson: null,
|
|
301
|
+
priorAndNextSteps,
|
|
302
|
+
isAlert: false,
|
|
303
|
+
isDrag: false,
|
|
304
|
+
},
|
|
305
|
+
input: { currentStep },
|
|
306
|
+
});
|
|
307
|
+
if (stepResult?.response?.variableName && stepResult.response.variableName.trim() !== "") {
|
|
308
|
+
currentReturnTypeVariableName = (0, elementSelectorResolver_js_1.generateUniqueName)(stepResult.response.variableName.trim(), usedVariableNames);
|
|
384
309
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
usedElementNames.push(elementName);
|
|
401
|
-
}
|
|
402
|
-
try {
|
|
403
|
-
if (platform == "web") {
|
|
404
|
-
driver = await context.session.getCurrentDriver();
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
driver = await context.mobileSession.getCurrentDriver();
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
catch (error) {
|
|
411
|
-
if (action == "verify") {
|
|
412
|
-
driver = null;
|
|
413
|
-
}
|
|
414
|
-
else {
|
|
415
|
-
throw error;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
if (await (0, isAlertPresent_js_1.isAlertPresent)(driver) && !["wait", "verify"].includes(action)) {
|
|
419
|
-
logData_js_1.logger.info("Alert is present");
|
|
420
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
421
|
-
platform: platform,
|
|
422
|
-
type: promptType_js_1.PromptType.FF_INSPECTOR,
|
|
423
|
-
args: {
|
|
424
|
-
stepAction: action,
|
|
425
|
-
extractedDomJson: null,
|
|
426
|
-
priorAndNextSteps,
|
|
427
|
-
isAlert: true,
|
|
428
|
-
isDrag: false
|
|
429
|
-
},
|
|
430
|
-
input: { currentStep: step }
|
|
431
|
-
});
|
|
432
|
-
stepAction = stepResult.response.action;
|
|
433
|
-
handler = actionHandlers[stepAction];
|
|
434
|
-
await handler({
|
|
435
|
-
value: stepResult.response.inputText
|
|
436
|
-
});
|
|
437
|
-
stepCount++;
|
|
438
|
-
continue;
|
|
439
|
-
}
|
|
440
|
-
else {
|
|
441
|
-
let toonDom;
|
|
442
|
-
if (preCapturedDomInfo && platform === "web") {
|
|
443
|
-
logData_js_1.logger.info("Using pre-captured DOM from previous toaster detection");
|
|
444
|
-
domInfo = preCapturedDomInfo;
|
|
445
|
-
preCapturedDomInfo = null;
|
|
446
|
-
const parser = new jsdom_1.JSDOM((0, domSanitizer_js_1.sanitizeWebDom)(domInfo.dom));
|
|
447
|
-
doc = parser.window.document;
|
|
448
|
-
}
|
|
449
|
-
else {
|
|
450
|
-
try {
|
|
451
|
-
if (platform === "web") {
|
|
452
|
-
domInfo = await (0, jsForAttributeInjection_js_1.getAnnotatedDOM)(driver);
|
|
453
|
-
logData_js_1.logger.saveDOM(domInfo.dom, `annotated-dom-${stepCount}`);
|
|
454
|
-
const parser = new jsdom_1.JSDOM((0, domSanitizer_js_1.sanitizeWebDom)(domInfo.dom));
|
|
455
|
-
doc = parser.window.document;
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
458
|
-
domInfo = await (0, jsForAttributeInjection_js_2.getAnnotatedDOMForMobile)(driver);
|
|
459
|
-
logData_js_1.logger.saveDOM(domInfo.dom, `annotated-dom-Mob-${stepCount}`);
|
|
460
|
-
const parser = new jsdom_1.JSDOM(domInfo.dom, {
|
|
461
|
-
contentType: "text/xml"
|
|
310
|
+
const otpAction = currentPlatform === "android" || currentPlatform === "ios"
|
|
311
|
+
? sameActionsHelper_js_1.sameActionHelper[stepResult.response.nlpName] || stepResult.response.nlpName
|
|
312
|
+
: stepResult.response.nlpName;
|
|
313
|
+
handler = actionHandlers[otpAction];
|
|
314
|
+
await handler({
|
|
315
|
+
selector: stepResult.response.inputText,
|
|
316
|
+
timeFrom: stepResult.response.timeFrom,
|
|
317
|
+
waitTime: stepResult.response.waitTime,
|
|
318
|
+
activity: stepResult.response.activity,
|
|
319
|
+
otpExtractor: async (smsBody) => {
|
|
320
|
+
const llmRes = await stepProcessor.getLLMResponse({
|
|
321
|
+
platform: currentPlatform,
|
|
322
|
+
type: promptType_js_1.PromptType.OTP_EXTRACTOR,
|
|
323
|
+
args: {},
|
|
324
|
+
input: { smsBody },
|
|
462
325
|
});
|
|
463
|
-
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
326
|
+
return llmRes.response;
|
|
327
|
+
},
|
|
328
|
+
stepIndex: stepCount,
|
|
329
|
+
currentStep,
|
|
330
|
+
manualStep: step,
|
|
331
|
+
stepsInputData,
|
|
332
|
+
returnTypeVariableName: currentReturnTypeVariableName,
|
|
333
|
+
});
|
|
334
|
+
stepCount++;
|
|
335
|
+
if (action?.toLowerCase() === "getotp") {
|
|
336
|
+
break;
|
|
473
337
|
}
|
|
338
|
+
continue;
|
|
474
339
|
}
|
|
340
|
+
currentElementName = (0, elementSelectorResolver_js_1.generateUniqueName)(currentElementName, usedElementNames);
|
|
475
341
|
try {
|
|
476
|
-
if (
|
|
477
|
-
|
|
478
|
-
keywords: result.response.keywords,
|
|
479
|
-
rawDom: domInfo.dom,
|
|
480
|
-
stepCount: stepCount,
|
|
481
|
-
stepAction: action,
|
|
482
|
-
step: step,
|
|
483
|
-
platform: platform,
|
|
484
|
-
driver: driver
|
|
485
|
-
});
|
|
486
|
-
toonDom = (0, toon_1.encode)(extractedRelevantDom || []);
|
|
487
|
-
// logger.saveJSON(extractedRelevantDom, `relevant-dom-${stepCount}`);
|
|
488
|
-
logData_js_1.logger.saveText(toonDom, `relevant-dom-toon-${stepCount}`);
|
|
342
|
+
if (currentPlatform === "web") {
|
|
343
|
+
driver = await context.session.getCurrentDriver();
|
|
489
344
|
}
|
|
490
345
|
else {
|
|
491
|
-
|
|
492
|
-
keywords: result.response.keywords,
|
|
493
|
-
rawDom: domInfo.dom,
|
|
494
|
-
stepCount: stepCount,
|
|
495
|
-
stepAction: action,
|
|
496
|
-
step: step,
|
|
497
|
-
platform: platform,
|
|
498
|
-
driver: driver
|
|
499
|
-
});
|
|
500
|
-
toonDom = (0, toon_1.encode)(extractedRelevantDom || []);
|
|
501
|
-
// logger.saveJSON(extractedRelevantDom, `relevant-dom-Mob-${stepCount}`);
|
|
502
|
-
logData_js_1.logger.saveText(toonDom, `relevant-dom-toon-Mob-${stepCount}`);
|
|
346
|
+
driver = await context.mobileSession.getCurrentDriver();
|
|
503
347
|
}
|
|
504
348
|
}
|
|
505
349
|
catch (error) {
|
|
506
|
-
if (action
|
|
507
|
-
|
|
350
|
+
if (action === "verify") {
|
|
351
|
+
driver = null;
|
|
508
352
|
}
|
|
509
353
|
else {
|
|
510
354
|
throw error;
|
|
511
355
|
}
|
|
512
356
|
}
|
|
513
|
-
if (
|
|
514
|
-
|
|
515
|
-
platform: platform,
|
|
516
|
-
type: promptType_js_1.PromptType.VERIFY_PROMPT,
|
|
517
|
-
args: {
|
|
518
|
-
extractedDomJson: toonDom,
|
|
519
|
-
priorAndNextSteps,
|
|
520
|
-
},
|
|
521
|
-
input: { currentStep: step }
|
|
522
|
-
});
|
|
523
|
-
stepAction = stepResult.response.nlpName;
|
|
524
|
-
}
|
|
525
|
-
else if (action == "get") {
|
|
357
|
+
if ((await (0, isAlertPresent_js_1.isAlertPresent)(driver)) && !["wait", "verify"].includes(action)) {
|
|
358
|
+
logData_js_1.logger.info("Alert is present");
|
|
526
359
|
stepResult = await stepProcessor.getLLMResponse({
|
|
527
|
-
platform:
|
|
528
|
-
type: promptType_js_1.PromptType.GET_PROMPT,
|
|
529
|
-
args: {
|
|
530
|
-
extractedDomJson: toonDom,
|
|
531
|
-
priorAndNextSteps,
|
|
532
|
-
},
|
|
533
|
-
input: { currentStep: step }
|
|
534
|
-
});
|
|
535
|
-
stepAction = stepResult.response.nlpName;
|
|
536
|
-
}
|
|
537
|
-
else if (action == "wait") {
|
|
538
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
539
|
-
platform: platform,
|
|
540
|
-
type: promptType_js_1.PromptType.WAIT_ACTION_EXTRACTOR_PROMPT,
|
|
541
|
-
args: {
|
|
542
|
-
extractedDomJson: toonDom,
|
|
543
|
-
priorAndNextSteps,
|
|
544
|
-
},
|
|
545
|
-
input: { currentStep: step }
|
|
546
|
-
});
|
|
547
|
-
stepAction = stepResult.response.nlpName;
|
|
548
|
-
}
|
|
549
|
-
else if (action == "combined") {
|
|
550
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
551
|
-
platform: platform,
|
|
552
|
-
type: promptType_js_1.PromptType.COMBINED_ACTION_EXTRACTOR_PROMPT,
|
|
553
|
-
args: {
|
|
554
|
-
extractedDomJson: toonDom,
|
|
555
|
-
priorAndNextSteps,
|
|
556
|
-
},
|
|
557
|
-
input: { currentStep: step }
|
|
558
|
-
});
|
|
559
|
-
stepAction = stepResult.response.nlpName;
|
|
560
|
-
}
|
|
561
|
-
else if (action == "drag_and_drop") {
|
|
562
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
563
|
-
platform: platform,
|
|
360
|
+
platform: currentPlatform,
|
|
564
361
|
type: promptType_js_1.PromptType.FF_INSPECTOR,
|
|
565
362
|
args: {
|
|
566
|
-
|
|
363
|
+
stepAction: action,
|
|
364
|
+
extractedDomJson: null,
|
|
567
365
|
priorAndNextSteps,
|
|
568
|
-
|
|
569
|
-
|
|
366
|
+
isAlert: true,
|
|
367
|
+
isDrag: false,
|
|
570
368
|
},
|
|
571
|
-
input: { currentStep
|
|
369
|
+
input: { currentStep },
|
|
572
370
|
});
|
|
573
|
-
stepAction = stepResult.response.
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
platform: platform,
|
|
578
|
-
type: promptType_js_1.PromptType.FF_INSPECTOR,
|
|
579
|
-
args: {
|
|
580
|
-
stepAction: action === "enterOtp" ? "enter" : action,
|
|
581
|
-
extractedDomJson: toonDom,
|
|
582
|
-
priorAndNextSteps,
|
|
583
|
-
isAlert: false,
|
|
584
|
-
isDrag: false
|
|
585
|
-
},
|
|
586
|
-
input: { currentStep: step }
|
|
371
|
+
stepAction = stepResult.response.action;
|
|
372
|
+
handler = actionHandlers[stepAction];
|
|
373
|
+
await handler({
|
|
374
|
+
value: stepResult.response.inputText,
|
|
587
375
|
});
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
}
|
|
591
|
-
else {
|
|
592
|
-
stepAction = stepResult.response.nlpName;
|
|
593
|
-
}
|
|
594
|
-
if ((action === "enterOtp" || stepAction === "enterOtp") && context.extractedOtp) {
|
|
595
|
-
stepResult.response.inputText = context.extractedOtp;
|
|
596
|
-
}
|
|
376
|
+
stepCount++;
|
|
377
|
+
continue;
|
|
597
378
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
if (supportedActions_js_1.SKIPPED_ACTIONS.includes(stepAction)) {
|
|
604
|
-
handler = actionHandlers[stepAction];
|
|
605
|
-
await handler();
|
|
606
|
-
stepCount++;
|
|
607
|
-
continue;
|
|
608
|
-
}
|
|
609
|
-
if (platform === "web") {
|
|
610
|
-
beforeHandles = await driver.getWindowHandles();
|
|
611
|
-
}
|
|
612
|
-
if (supportedActions_js_1.ELEMENTLESS_ACTION.includes(stepAction)) {
|
|
613
|
-
let currentDriver = null;
|
|
614
|
-
let beforeHandles = null;
|
|
615
|
-
if (platform == "web") {
|
|
616
|
-
currentDriver = await context.session.getCurrentDriver();
|
|
617
|
-
beforeHandles = await currentDriver.getWindowHandles();
|
|
379
|
+
if (preCapturedDomInfo && currentPlatform === "web") {
|
|
380
|
+
logData_js_1.logger.info("Using pre-captured DOM from previous toaster detection");
|
|
381
|
+
domInfo = preCapturedDomInfo;
|
|
382
|
+
preCapturedDomInfo = null;
|
|
383
|
+
doc = runnerDomPipeline_js_1.RunnerDomPipeline.parseDomDocument(domInfo.dom, "web");
|
|
618
384
|
}
|
|
619
385
|
else {
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
386
|
+
const domResult = await runnerDomPipeline_js_1.RunnerDomPipeline.captureAndParseDom(driver, currentPlatform, stepCount, action, false);
|
|
387
|
+
domInfo = domResult.domInfo;
|
|
388
|
+
doc = domResult.doc;
|
|
389
|
+
}
|
|
390
|
+
const relevantDomResult = await runnerDomPipeline_js_1.RunnerDomPipeline.processRelevantDom(domProcessor, domInfo, keywords, stepCount, action, currentStep, currentPlatform, driver, false);
|
|
391
|
+
extractedRelevantDom = relevantDomResult.extractedRelevantDom;
|
|
392
|
+
const toonDom = relevantDomResult.toonDom;
|
|
393
|
+
const actionResolution = await (0, stepActionInspector_js_1.resolveStepActionFromDom)(stepProcessor, currentPlatform, action, toonDom, priorAndNextSteps, currentStep, stepObj.fileType ?? null);
|
|
394
|
+
stepResult = actionResolution.stepResult;
|
|
395
|
+
stepAction = actionResolution.stepAction;
|
|
396
|
+
if (stepResult?.response?.variableName && stepResult.response.variableName.trim() !== "") {
|
|
397
|
+
currentReturnTypeVariableName = (0, elementSelectorResolver_js_1.generateUniqueName)(stepResult.response.variableName.trim(), usedVariableNames);
|
|
398
|
+
}
|
|
399
|
+
const inputContextResult = inputContextPromise ? await inputContextPromise : null;
|
|
400
|
+
const inputText = inputContextResult?.response?.inputText;
|
|
401
|
+
if (inputContextResult?.response?.variableName && inputContextResult.response.variableName.trim() !== "") {
|
|
402
|
+
currentVariableName = inputContextResult.response.variableName.trim();
|
|
403
|
+
}
|
|
404
|
+
inputValue =
|
|
405
|
+
inputText && inputText.trim().length > 0
|
|
406
|
+
? inputText
|
|
407
|
+
: stepResult?.response?.inputText;
|
|
408
|
+
if (supportedActions_js_1.SKIPPED_ACTIONS.includes(stepAction)) {
|
|
409
|
+
handler = actionHandlers[stepAction];
|
|
410
|
+
await handler();
|
|
640
411
|
stepCount++;
|
|
641
412
|
continue;
|
|
642
413
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
selector: stepResult.response.attributeValue,
|
|
646
|
-
elementName: result.response.elementName,
|
|
647
|
-
elementType: stepResult.response.elementType
|
|
648
|
-
});
|
|
649
|
-
if ((currentDriver) && (platform == "web")) {
|
|
650
|
-
await (0, newTabTracker_js_1.newTabTracker)(currentDriver, action, beforeHandles, context.scriptAppender);
|
|
414
|
+
if (currentPlatform === "web") {
|
|
415
|
+
beforeHandles = await driver.getWindowHandles();
|
|
651
416
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
if (fallbackAttempt > 1) {
|
|
659
|
-
logData_js_1.logger.info(`Waiting 5 seconds before retrying step "${step}". Attempt ${fallbackAttempt}`);
|
|
660
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
661
|
-
logData_js_1.logger.info(`Retrying step "${step}" after vision fallback failure. Attempt ${fallbackAttempt}`);
|
|
662
|
-
// if (result.response.liveLog) {
|
|
663
|
-
// await produceLiveLog(result.response.liveLog);
|
|
664
|
-
// }
|
|
665
|
-
stepAction = baseStepActionBeforeFallback;
|
|
666
|
-
selector = "";
|
|
667
|
-
xpath = "";
|
|
668
|
-
iframeDomHtml = null;
|
|
669
|
-
beforeHandles = null;
|
|
670
|
-
if (platform === "web") {
|
|
671
|
-
domInfo = await (0, jsForAttributeInjection_js_1.getAnnotatedDOM)(driver);
|
|
672
|
-
logData_js_1.logger.saveDOM(domInfo.dom, `annotated-dom-retry-${stepCount}`);
|
|
673
|
-
const parser = new jsdom_1.JSDOM((0, domSanitizer_js_1.sanitizeWebDom)(domInfo.dom));
|
|
674
|
-
doc = parser.window.document;
|
|
675
|
-
}
|
|
676
|
-
else {
|
|
677
|
-
domInfo = await (0, jsForAttributeInjection_js_2.getAnnotatedDOMForMobile)(driver);
|
|
678
|
-
logData_js_1.logger.saveDOM(domInfo.dom, `annotated-dom-Mob-retry-${stepCount}`);
|
|
679
|
-
const parser = new jsdom_1.JSDOM(domInfo.dom, {
|
|
680
|
-
contentType: "text/xml"
|
|
681
|
-
});
|
|
682
|
-
doc = parser.window.document;
|
|
683
|
-
}
|
|
684
|
-
let retryToonDom;
|
|
685
|
-
if (platform === "web") {
|
|
686
|
-
extractedRelevantDom = await domProcessor.webProcess({
|
|
687
|
-
keywords: result.response.keywords,
|
|
688
|
-
rawDom: domInfo.dom,
|
|
689
|
-
stepCount: stepCount,
|
|
690
|
-
stepAction: action,
|
|
691
|
-
step: step,
|
|
692
|
-
platform: platform,
|
|
693
|
-
driver: driver
|
|
694
|
-
});
|
|
695
|
-
retryToonDom = (0, toon_1.encode)(extractedRelevantDom || []);
|
|
696
|
-
logData_js_1.logger.saveText(retryToonDom, `relevant-dom-toon-retry-${stepCount}`);
|
|
697
|
-
}
|
|
698
|
-
else {
|
|
699
|
-
extractedRelevantDom = await domProcessor.mobileProcess({
|
|
700
|
-
keywords: result.response.keywords,
|
|
701
|
-
rawDom: domInfo.dom,
|
|
702
|
-
stepCount: stepCount,
|
|
703
|
-
stepAction: action,
|
|
704
|
-
step: step,
|
|
705
|
-
platform: platform,
|
|
706
|
-
driver: driver
|
|
707
|
-
});
|
|
708
|
-
retryToonDom = (0, toon_1.encode)(extractedRelevantDom || []);
|
|
709
|
-
logData_js_1.logger.saveText(retryToonDom, `relevant-dom-toon-Mob-retry-${stepCount}`);
|
|
710
|
-
}
|
|
711
|
-
if (action == "verify") {
|
|
712
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
713
|
-
platform: platform,
|
|
714
|
-
type: promptType_js_1.PromptType.VERIFY_PROMPT,
|
|
715
|
-
args: {
|
|
716
|
-
extractedDomJson: retryToonDom,
|
|
717
|
-
priorAndNextSteps,
|
|
718
|
-
},
|
|
719
|
-
input: { currentStep: step }
|
|
720
|
-
});
|
|
721
|
-
stepAction = stepResult.response.nlpName;
|
|
722
|
-
}
|
|
723
|
-
else if (action == "get") {
|
|
724
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
725
|
-
platform: platform,
|
|
726
|
-
type: promptType_js_1.PromptType.GET_PROMPT,
|
|
727
|
-
args: {
|
|
728
|
-
extractedDomJson: retryToonDom,
|
|
729
|
-
priorAndNextSteps,
|
|
730
|
-
},
|
|
731
|
-
input: { currentStep: step }
|
|
732
|
-
});
|
|
733
|
-
stepAction = stepResult.response.nlpName;
|
|
734
|
-
}
|
|
735
|
-
else if (action == "wait") {
|
|
736
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
737
|
-
platform: platform,
|
|
738
|
-
type: promptType_js_1.PromptType.WAIT_ACTION_EXTRACTOR_PROMPT,
|
|
739
|
-
args: {
|
|
740
|
-
extractedDomJson: retryToonDom,
|
|
741
|
-
priorAndNextSteps,
|
|
742
|
-
},
|
|
743
|
-
input: { currentStep: step }
|
|
744
|
-
});
|
|
745
|
-
stepAction = stepResult.response.nlpName;
|
|
746
|
-
}
|
|
747
|
-
else if (action == "combined") {
|
|
748
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
749
|
-
platform: platform,
|
|
750
|
-
type: promptType_js_1.PromptType.COMBINED_ACTION_EXTRACTOR_PROMPT,
|
|
751
|
-
args: {
|
|
752
|
-
extractedDomJson: retryToonDom,
|
|
753
|
-
priorAndNextSteps,
|
|
754
|
-
},
|
|
755
|
-
input: { currentStep: step }
|
|
756
|
-
});
|
|
757
|
-
stepAction = stepResult.response.nlpName;
|
|
758
|
-
}
|
|
759
|
-
else if (action == "drag_and_drop") {
|
|
760
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
761
|
-
platform: platform,
|
|
762
|
-
type: promptType_js_1.PromptType.FF_INSPECTOR,
|
|
763
|
-
args: {
|
|
764
|
-
extractedDomJson: retryToonDom,
|
|
765
|
-
priorAndNextSteps,
|
|
766
|
-
isDrag: true,
|
|
767
|
-
isAlert: false
|
|
768
|
-
},
|
|
769
|
-
input: { currentStep: step }
|
|
770
|
-
});
|
|
771
|
-
stepAction = stepResult.response.nlpName;
|
|
772
|
-
}
|
|
773
|
-
else {
|
|
774
|
-
stepResult = await stepProcessor.getLLMResponse({
|
|
775
|
-
platform: platform,
|
|
776
|
-
type: promptType_js_1.PromptType.FF_INSPECTOR,
|
|
777
|
-
args: {
|
|
778
|
-
stepAction: action,
|
|
779
|
-
extractedDomJson: retryToonDom,
|
|
780
|
-
priorAndNextSteps,
|
|
781
|
-
isAlert: false,
|
|
782
|
-
isDrag: false
|
|
783
|
-
},
|
|
784
|
-
input: { currentStep: step }
|
|
785
|
-
});
|
|
786
|
-
stepAction = platform == "web"
|
|
787
|
-
? stepResult.response.action
|
|
788
|
-
: stepResult.response.nlpName;
|
|
789
|
-
}
|
|
790
|
-
if (platform === "android" || platform === "ios") {
|
|
791
|
-
stepAction = sameActionsHelper_js_1.sameActionHelper[stepAction] || stepAction;
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
if (stepAction == "Builtin_DragAndDropToElement") {
|
|
795
|
-
handler = actionHandlers[stepAction];
|
|
796
|
-
const fireflinkIndex1 = stepResult.response.drag;
|
|
797
|
-
const ele1 = doc.querySelector(`[ff-inspect="${fireflinkIndex1}"]`);
|
|
798
|
-
const selector1 = ele1?.getAttribute("ff-xpath");
|
|
799
|
-
const fireflinkIndex2 = stepResult.response.drop;
|
|
800
|
-
const ele2 = doc.querySelector(`[ff-inspect="${fireflinkIndex2}"]`);
|
|
801
|
-
const selector2 = ele2?.getAttribute("ff-xpath");
|
|
802
|
-
if (!selector2 && !selector1) {
|
|
803
|
-
throw new Error(`Unable to resolve xpath for ${fireflinkIndex2}`);
|
|
804
|
-
}
|
|
805
|
-
else if (fireflinkIndex2 == "Fire-Flink-0" && fireflinkIndex1 == "Fire-Flink-0") {
|
|
806
|
-
throw new Error(`Unable to find element for ${step}`);
|
|
807
|
-
}
|
|
417
|
+
if (supportedActions_js_1.ELEMENTLESS_ACTION.includes(stepAction)) {
|
|
418
|
+
const currentDriver = currentPlatform === "web"
|
|
419
|
+
? await context.session.getCurrentDriver()
|
|
420
|
+
: await context.mobileSession.getCurrentDriver();
|
|
421
|
+
handler = actionHandlers[stepAction];
|
|
422
|
+
if (stepAction === "getOtp") {
|
|
808
423
|
await handler({
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
424
|
+
selector: stepResult.response.inputText,
|
|
425
|
+
activity: stepResult.response.activity,
|
|
426
|
+
isTerminated: () => AutomationRunner.getSessionTerminationInfo(request.testCaseId),
|
|
427
|
+
otpExtractor: async (smsBody) => {
|
|
428
|
+
const llmRes = await stepProcessor.getLLMResponse({
|
|
429
|
+
platform: currentPlatform,
|
|
430
|
+
type: promptType_js_1.PromptType.OTP_EXTRACTOR,
|
|
431
|
+
args: {},
|
|
432
|
+
input: { smsBody },
|
|
433
|
+
});
|
|
434
|
+
return llmRes.response;
|
|
435
|
+
},
|
|
436
|
+
stepIndex: currentStepIndex,
|
|
437
|
+
currentStep,
|
|
438
|
+
manualStep: step,
|
|
439
|
+
stepsInputData,
|
|
440
|
+
returnTypeVariableName: currentReturnTypeVariableName,
|
|
818
441
|
});
|
|
442
|
+
stepCount++;
|
|
819
443
|
continue;
|
|
820
444
|
}
|
|
821
|
-
fireflinkIndex = stepResult.response.attributeValue;
|
|
822
|
-
if (fireflinkIndex == "Fire-Flink-0") {
|
|
823
|
-
logData_js_1.logger.error(`element not found for step "${step}"`);
|
|
824
|
-
throw new Error(`element not found for step "${step}"`, { cause: node_console_1.error });
|
|
825
|
-
}
|
|
826
|
-
if (platform === "web") {
|
|
827
|
-
if (!doc) {
|
|
828
|
-
logData_js_1.logger.info("doc is undefined. Rebuilding document from domInfo.");
|
|
829
|
-
if (!domInfo || !domInfo.dom) {
|
|
830
|
-
domInfo = await (0, jsForAttributeInjection_js_1.getAnnotatedDOM)(driver);
|
|
831
|
-
}
|
|
832
|
-
const parser = new jsdom_1.JSDOM((0, domSanitizer_js_1.sanitizeWebDom)(domInfo.dom));
|
|
833
|
-
doc = parser.window.document;
|
|
834
|
-
}
|
|
835
|
-
const ele = doc.querySelector(`[ff-inspect="${fireflinkIndex}"]`);
|
|
836
|
-
if (ele) {
|
|
837
|
-
selector = ele.getAttribute("ff-xpath") || "";
|
|
838
|
-
}
|
|
839
|
-
else {
|
|
840
|
-
const result = (0, xpathcreation_js_1.getWebXPathByFFIndex)(domInfo.dom, fireflinkIndex);
|
|
841
|
-
selector = result.xpathPath;
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
else {
|
|
845
|
-
const result = await (0, xpathcreation_js_1.getFFIndexAndXPath)(domInfo.dom, fireflinkIndex);
|
|
846
|
-
selector = result.xpathPath;
|
|
847
|
-
}
|
|
848
|
-
if (!selector) {
|
|
849
|
-
logData_js_1.logger.info(`Unable to resolve xpath for ${fireflinkIndex}`);
|
|
850
|
-
throw new Error(`Unable to resolve xpath for ${fireflinkIndex}`, { cause: node_console_1.error });
|
|
851
|
-
}
|
|
852
|
-
if (selector.includes("shadow")) {
|
|
853
|
-
stepAction = stepAction + "_shadow";
|
|
854
|
-
logData_js_1.logger.info(stepAction);
|
|
855
|
-
}
|
|
856
|
-
else if (selector.includes("iframe")) {
|
|
857
|
-
frameAction = "switchToDefaultContent";
|
|
858
|
-
handler = actionHandlers[frameAction];
|
|
859
|
-
await handler({
|
|
860
|
-
driver: driver,
|
|
861
|
-
});
|
|
862
|
-
const result_if = await driver.executeAsyncScript(jsFindElement_js_1.Find_element_by_ff_js_script, [fireflinkIndex]);
|
|
863
|
-
if (!result_if?.success) {
|
|
864
|
-
logData_js_1.logger.info("Not found");
|
|
865
|
-
return;
|
|
866
|
-
}
|
|
867
|
-
const { xpath_if, frames, iframe_dom_html } = result_if;
|
|
868
|
-
selector = xpath_if;
|
|
869
|
-
iframeDomHtml = iframe_dom_html;
|
|
870
|
-
frameAction = "switchToFrame";
|
|
871
|
-
handler = actionHandlers[frameAction];
|
|
872
|
-
await handler({
|
|
873
|
-
selector: selector,
|
|
874
|
-
frames: frames,
|
|
875
|
-
elementName: result.response.elementName,
|
|
876
|
-
elementType: stepResult.response.elementType,
|
|
877
|
-
pageDOM: domInfo.dom,
|
|
878
|
-
fireflinkIndex
|
|
879
|
-
});
|
|
880
|
-
}
|
|
881
|
-
if (selector.includes('svg')) {
|
|
882
|
-
const match = /svg\[(\d+)\]/.exec(selector);
|
|
883
|
-
const svgIndex = match ? match[1] : "1";
|
|
884
|
-
selector = selector.replace(/svg\[\d+\]/, `*[name()='svg'][${svgIndex}]`);
|
|
885
|
-
}
|
|
886
|
-
pageDOM = iframeDomHtml ?? domInfo.dom;
|
|
887
|
-
handler = actionHandlers[stepAction];
|
|
888
|
-
// logger.info(`xpath ------>: ${selector}`)
|
|
889
445
|
await handler({
|
|
890
|
-
|
|
891
|
-
selector:
|
|
892
|
-
|
|
893
|
-
fireflinkIndex,
|
|
894
|
-
pageDOM: pageDOM,
|
|
895
|
-
elementName: result.response.elementName,
|
|
446
|
+
value: inputValue,
|
|
447
|
+
selector: stepResult.response.attributeValue,
|
|
448
|
+
elementName: currentElementName || result.response.elementName,
|
|
896
449
|
elementType: stepResult.response.elementType,
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
450
|
+
stepIndex: currentStepIndex,
|
|
451
|
+
currentStep,
|
|
452
|
+
manualStep: step,
|
|
453
|
+
stepsInputData,
|
|
454
|
+
returnTypeVariableName: currentReturnTypeVariableName,
|
|
455
|
+
...(currentVariableName ? { variableName: currentVariableName } : {}),
|
|
902
456
|
});
|
|
903
|
-
if (
|
|
904
|
-
|
|
905
|
-
if (action === "click") {
|
|
906
|
-
await driver.executeScript(jsForToaster_js_1.TOAST_WATCHER_JS, []);
|
|
907
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
908
|
-
const postClickToastDetected = await driver.executeScript("return window.__toastDetected === true;", []);
|
|
909
|
-
if (postClickToastDetected) {
|
|
910
|
-
logData_js_1.logger.info(`Toast detected after click`);
|
|
911
|
-
preCapturedDomInfo = await (0, jsForAttributeInjection_js_1.getAnnotatedDOM)(driver);
|
|
912
|
-
logData_js_1.logger.saveDOM(preCapturedDomInfo.dom, `toaster-dom-${stepCount}`);
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
if (beforeHandles?.length > 0) {
|
|
917
|
-
await (0, newTabTracker_js_1.newTabTracker)(driver, action, beforeHandles, context.scriptAppender);
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
if (fallbackAttempt === 2) {
|
|
921
|
-
await produceLiveLog("Retry successful. Moving on to the next step.");
|
|
457
|
+
if (currentDriver && currentPlatform === "web") {
|
|
458
|
+
await (0, newTabTracker_js_1.newTabTracker)(currentDriver, action, beforeHandles, context.scriptAppender);
|
|
922
459
|
}
|
|
923
|
-
|
|
460
|
+
stepCount++;
|
|
461
|
+
continue;
|
|
924
462
|
}
|
|
925
|
-
|
|
926
|
-
|
|
463
|
+
baseStepActionBeforeFallback = stepAction;
|
|
464
|
+
for (let fallbackAttempt = 1; fallbackAttempt <= 2; fallbackAttempt++) {
|
|
927
465
|
try {
|
|
928
|
-
let
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
466
|
+
let iframeDomHtml = null;
|
|
467
|
+
if (fallbackAttempt > 1) {
|
|
468
|
+
logData_js_1.logger.info(`Waiting 5 seconds before retrying step "${step}". Attempt ${fallbackAttempt}`);
|
|
469
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
470
|
+
logData_js_1.logger.info(`Retrying step "${step}" after vision fallback failure. Attempt ${fallbackAttempt}`);
|
|
471
|
+
stepAction = baseStepActionBeforeFallback;
|
|
472
|
+
selector = "";
|
|
473
|
+
iframeDomHtml = null;
|
|
474
|
+
beforeHandles = null;
|
|
475
|
+
const retryDomResult = await runnerDomPipeline_js_1.RunnerDomPipeline.captureAndParseDom(driver, currentPlatform, stepCount, action, true);
|
|
476
|
+
domInfo = retryDomResult.domInfo;
|
|
477
|
+
doc = retryDomResult.doc;
|
|
478
|
+
const retryRelevantResult = await runnerDomPipeline_js_1.RunnerDomPipeline.processRelevantDom(domProcessor, domInfo, keywords, stepCount, action, currentStep, currentPlatform, driver, true);
|
|
479
|
+
extractedRelevantDom = retryRelevantResult.extractedRelevantDom;
|
|
480
|
+
const retryToonDom = retryRelevantResult.toonDom;
|
|
481
|
+
const retryActionResolution = await (0, stepActionInspector_js_1.resolveStepActionFromDom)(stepProcessor, currentPlatform, action, retryToonDom, priorAndNextSteps, currentStep, null);
|
|
482
|
+
stepResult = retryActionResolution.stepResult;
|
|
483
|
+
stepAction = retryActionResolution.stepAction;
|
|
484
|
+
}
|
|
485
|
+
if (stepAction === "Builtin_DragAndDropToElement") {
|
|
486
|
+
handler = actionHandlers[stepAction];
|
|
487
|
+
const fireflinkIndex1 = stepResult.response.drag;
|
|
488
|
+
const ele1 = doc.querySelector(`[ff-inspect="${fireflinkIndex1}"]`);
|
|
489
|
+
const selector1 = ele1?.getAttribute("ff-xpath");
|
|
490
|
+
const fireflinkIndex2 = stepResult.response.drop;
|
|
491
|
+
const ele2 = doc.querySelector(`[ff-inspect="${fireflinkIndex2}"]`);
|
|
492
|
+
const selector2 = ele2?.getAttribute("ff-xpath");
|
|
493
|
+
if (!selector2 && !selector1) {
|
|
494
|
+
throw new Error(`Unable to resolve xpath for ${fireflinkIndex2}`);
|
|
944
495
|
}
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
}
|
|
948
|
-
if (platform == "web") {
|
|
949
|
-
stepResultVision = await stepProcessor.getLLMResponse({
|
|
950
|
-
platform: platform,
|
|
951
|
-
type: promptType_js_1.PromptType.VISION_PROMPT,
|
|
952
|
-
args: {
|
|
953
|
-
priorAndNextSteps
|
|
954
|
-
},
|
|
955
|
-
input: { currentStep: step, annotatedScreenshot: annotatedScreenshot.primary },
|
|
956
|
-
isVision: true
|
|
957
|
-
});
|
|
958
|
-
if (stepResultVision.response.fireflinkIndex == "Fire-Flink-0") {
|
|
959
|
-
stepResultVision = await stepProcessor.getLLMResponse({
|
|
960
|
-
platform: platform,
|
|
961
|
-
type: promptType_js_1.PromptType.VISION_PROMPT,
|
|
962
|
-
args: {
|
|
963
|
-
priorAndNextSteps
|
|
964
|
-
},
|
|
965
|
-
input: { currentStep: step, annotatedScreenshot: annotatedScreenshot.secondary },
|
|
966
|
-
isVision: true
|
|
967
|
-
});
|
|
496
|
+
else if (fireflinkIndex2 === "Fire-Flink-0" && fireflinkIndex1 === "Fire-Flink-0") {
|
|
497
|
+
throw new Error(`Unable to find element for ${step}`);
|
|
968
498
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
499
|
+
await handler({
|
|
500
|
+
selector1,
|
|
501
|
+
selector2,
|
|
502
|
+
fireflinkIndex1,
|
|
503
|
+
fireflinkIndex2,
|
|
504
|
+
pageDOM: domInfo.dom,
|
|
505
|
+
elementName1: stepResult.response.drag_element_name,
|
|
506
|
+
elementName2: stepResult.response.drop_element_name,
|
|
507
|
+
elementType1: stepResult.response.drag_element_type,
|
|
508
|
+
elementType2: stepResult.response.drop_element_type,
|
|
979
509
|
});
|
|
510
|
+
continue;
|
|
980
511
|
}
|
|
981
|
-
fireflinkIndex =
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
if (
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
const boundsStr = `[${x1},${y1}][${x2},${y2}]`;
|
|
998
|
-
const result = (0, xpathcreation_js_1.getFFIndexAndXPath)(domInfo.dom, boundsStr, platform);
|
|
999
|
-
xpath = result.xpathPath;
|
|
1000
|
-
fireflinkIndex = result.ffInspector ?? fireflinkIndex;
|
|
1001
|
-
}
|
|
1002
|
-
else {
|
|
1003
|
-
if (!domInfo || !domInfo.dom || !doc) {
|
|
1004
|
-
logData_js_1.logger.info("Re-fetching annotated DOM for vision fallback");
|
|
1005
|
-
domInfo = await (0, jsForAttributeInjection_js_1.getAnnotatedDOM)(driver);
|
|
1006
|
-
const parser = new jsdom_1.JSDOM((0, domSanitizer_js_1.sanitizeWebDom)(domInfo.dom));
|
|
1007
|
-
doc = parser.window.document;
|
|
1008
|
-
}
|
|
1009
|
-
const ele = doc.querySelector(`[ff-inspect="${fireflinkIndex}"]`);
|
|
1010
|
-
if (ele) {
|
|
1011
|
-
xpath = ele.getAttribute("ff-xpath") || "";
|
|
1012
|
-
}
|
|
1013
|
-
else {
|
|
1014
|
-
const result = (0, xpathcreation_js_1.getWebXPathByFFIndex)(domInfo.dom, fireflinkIndex);
|
|
1015
|
-
xpath = result.xpathPath;
|
|
1016
|
-
}
|
|
1017
|
-
if (!xpath) {
|
|
1018
|
-
context.scriptAppender.setErrorNLP(stepAction);
|
|
1019
|
-
throw new Error(`Unable to resolve xpath for ${fireflinkIndex}`, { cause: error });
|
|
1020
|
-
}
|
|
512
|
+
fireflinkIndex = stepResult.response.attributeValue;
|
|
513
|
+
if (fireflinkIndex === "Fire-Flink-0") {
|
|
514
|
+
logData_js_1.logger.error(`element not found for step "${step}"`);
|
|
515
|
+
throw new Error(`element not found for step "${step}"`);
|
|
516
|
+
}
|
|
517
|
+
const selectorResult = await (0, elementSelectorResolver_js_1.resolveElementSelector)(doc, domInfo, fireflinkIndex, currentPlatform, driver);
|
|
518
|
+
selector = selectorResult.selector;
|
|
519
|
+
doc = selectorResult.doc;
|
|
520
|
+
domInfo = selectorResult.domInfo;
|
|
521
|
+
if (!selector) {
|
|
522
|
+
logData_js_1.logger.info(`Unable to resolve xpath for ${fireflinkIndex}`);
|
|
523
|
+
throw new Error(`Unable to resolve xpath for ${fireflinkIndex}`);
|
|
524
|
+
}
|
|
525
|
+
const shadowIframeResult = await (0, elementSelectorResolver_js_1.handleShadowAndIframe)(driver, stepAction, selector, fireflinkIndex, domInfo, actionHandlers, currentElementName || result.response.elementName, stepResult.response.elementType);
|
|
526
|
+
if (!shadowIframeResult.handled) {
|
|
527
|
+
return;
|
|
1021
528
|
}
|
|
529
|
+
stepAction = shadowIframeResult.stepAction;
|
|
530
|
+
selector = shadowIframeResult.selector;
|
|
531
|
+
iframeDomHtml = shadowIframeResult.iframeDomHtml;
|
|
1022
532
|
pageDOM = iframeDomHtml ?? domInfo.dom;
|
|
1023
533
|
handler = actionHandlers[stepAction];
|
|
1024
534
|
await handler({
|
|
1025
|
-
|
|
1026
|
-
|
|
535
|
+
nlpName: stepResult.response.nlpName,
|
|
536
|
+
selector,
|
|
537
|
+
value: inputValue,
|
|
1027
538
|
fireflinkIndex,
|
|
1028
|
-
pageDOM
|
|
1029
|
-
elementName: result.response.elementName,
|
|
539
|
+
pageDOM,
|
|
540
|
+
elementName: currentElementName || result.response.elementName,
|
|
1030
541
|
elementType: stepResult.response.elementType,
|
|
1031
|
-
|
|
1032
|
-
|
|
542
|
+
numOfScrolls: stepResult.response.numOfScrolls,
|
|
543
|
+
direction: stepResult.response.direction,
|
|
544
|
+
stepIndex: currentStepIndex,
|
|
545
|
+
filteredSteps: listOfSteps,
|
|
546
|
+
attributeType: stepResult.response.attributeType,
|
|
547
|
+
currentStep,
|
|
548
|
+
manualStep: step,
|
|
549
|
+
stepsInputData,
|
|
550
|
+
returnTypeVariableName: currentReturnTypeVariableName,
|
|
551
|
+
...(currentVariableName ? { variableName: currentVariableName } : {}),
|
|
1033
552
|
});
|
|
1034
|
-
|
|
1035
|
-
if (await (0, isAlertPresent_js_1.isAlertPresent)(driver) != true) {
|
|
1036
|
-
if (action === "click") {
|
|
1037
|
-
await driver.executeScript(jsForToaster_js_1.TOAST_WATCHER_JS, []);
|
|
1038
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
1039
|
-
const postClickToastDetected = await driver.executeScript("return window.__toastDetected === true;", []);
|
|
1040
|
-
if (postClickToastDetected) {
|
|
1041
|
-
logData_js_1.logger.info(`Toast detected after click`);
|
|
1042
|
-
preCapturedDomInfo = await (0, jsForAttributeInjection_js_1.getAnnotatedDOM)(driver);
|
|
1043
|
-
logData_js_1.logger.saveDOM(preCapturedDomInfo.dom, `toaster-dom-${stepCount}`);
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
if (beforeHandles?.length > 0) {
|
|
1048
|
-
await (0, newTabTracker_js_1.newTabTracker)(driver, action, beforeHandles, context.scriptAppender);
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
553
|
+
preCapturedDomInfo = await (0, runnerPostActionHelper_js_1.handlePostActionWeb)(currentPlatform, driver, action, beforeHandles, context.scriptAppender, stepCount);
|
|
1051
554
|
if (fallbackAttempt === 2) {
|
|
1052
|
-
await
|
|
555
|
+
await reporter.sendRetry("Retry successful. Moving on to the next step.");
|
|
1053
556
|
}
|
|
1054
557
|
break;
|
|
1055
558
|
}
|
|
1056
559
|
catch (error) {
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
560
|
+
const visionResult = await (0, visionFallbackHandler_js_1.executeVisionFallback)({
|
|
561
|
+
driver,
|
|
562
|
+
platform: currentPlatform,
|
|
563
|
+
action,
|
|
564
|
+
step,
|
|
565
|
+
stepAction,
|
|
566
|
+
inputValue,
|
|
567
|
+
stepCount,
|
|
568
|
+
stepIndex: currentStepIndex,
|
|
569
|
+
currentStep,
|
|
570
|
+
manualStep: step,
|
|
571
|
+
stepsInputData,
|
|
572
|
+
returnTypeVariableName: currentReturnTypeVariableName,
|
|
573
|
+
variableName: currentVariableName,
|
|
574
|
+
fallbackAttempt,
|
|
575
|
+
priorAndNextSteps,
|
|
576
|
+
listOfSteps,
|
|
577
|
+
currentElementName,
|
|
578
|
+
extractorElementName: result.response.elementName,
|
|
579
|
+
stepElementType: stepResult.response.elementType,
|
|
580
|
+
iframeDomHtml: null,
|
|
581
|
+
domInfo,
|
|
582
|
+
doc,
|
|
583
|
+
beforeHandles,
|
|
584
|
+
context,
|
|
585
|
+
stepProcessor,
|
|
586
|
+
actionHandlers,
|
|
587
|
+
reporter,
|
|
588
|
+
causeError: error,
|
|
589
|
+
});
|
|
590
|
+
if (visionResult.retryNeeded) {
|
|
1060
591
|
continue;
|
|
1061
592
|
}
|
|
1062
|
-
|
|
593
|
+
preCapturedDomInfo = visionResult.preCapturedDomInfo;
|
|
594
|
+
break;
|
|
1063
595
|
}
|
|
1064
596
|
}
|
|
597
|
+
baseStepActionBeforeFallback = stepAction;
|
|
598
|
+
domInfo = null;
|
|
599
|
+
extractedRelevantDom = null;
|
|
600
|
+
stepCount++;
|
|
1065
601
|
}
|
|
1066
|
-
baseStepActionBeforeFallback = stepAction;
|
|
1067
|
-
domInfo = null;
|
|
1068
|
-
extractedRelevantDom = null;
|
|
1069
|
-
stepCount++;
|
|
1070
602
|
}
|
|
1071
603
|
catch (error) {
|
|
1072
604
|
logData_js_1.logger.error(`Error executing step "${step}":`, error);
|
|
@@ -1080,7 +612,12 @@ class AutomationRunner {
|
|
|
1080
612
|
errorInfo.rawError = logData_js_1.logger.getError(error);
|
|
1081
613
|
break;
|
|
1082
614
|
}
|
|
1083
|
-
errorInfo = (await stepProcessor.getLLMResponse({
|
|
615
|
+
errorInfo = (await stepProcessor.getLLMResponse({
|
|
616
|
+
platform: currentPlatform,
|
|
617
|
+
type: promptType_js_1.PromptType.ERROR_DESCRIPTION,
|
|
618
|
+
args: {},
|
|
619
|
+
input: { error: logData_js_1.logger.getError(error) },
|
|
620
|
+
})).response;
|
|
1084
621
|
if (context.scriptAppender.getErrorNLP()) {
|
|
1085
622
|
errorInfo.nlp = context.scriptAppender.getErrorNLP();
|
|
1086
623
|
}
|
|
@@ -1089,7 +626,7 @@ class AutomationRunner {
|
|
|
1089
626
|
break;
|
|
1090
627
|
}
|
|
1091
628
|
}
|
|
1092
|
-
logData_js_1.logger.info(
|
|
629
|
+
logData_js_1.logger.info("execution time->", new Date().getTime() - startTime);
|
|
1093
630
|
const payload = {
|
|
1094
631
|
scriptName: request.scriptName ?? "SCRIPT_NAME",
|
|
1095
632
|
type: request.type,
|
|
@@ -1101,154 +638,29 @@ class AutomationRunner {
|
|
|
1101
638
|
licenseId: request.licenseId,
|
|
1102
639
|
userId: request.userId,
|
|
1103
640
|
projectType: request.projectType,
|
|
1104
|
-
platform: (0, platformSyntax_js_1.getPlatformSyntax)(
|
|
641
|
+
platform: (0, platformSyntax_js_1.getPlatformSyntax)(currentPlatform),
|
|
1105
642
|
tokensConsumed: (await stepProcessor.getResultTokenUsage()).totalTokens,
|
|
1106
643
|
};
|
|
1107
644
|
this.KafkaPayload.topic = request.topic;
|
|
1108
645
|
let keepSessionAlive = false;
|
|
1109
646
|
try {
|
|
1110
|
-
if (
|
|
1111
|
-
await
|
|
1112
|
-
|
|
1113
|
-
topic: "",
|
|
1114
|
-
service: "",
|
|
1115
|
-
chatId: "",
|
|
1116
|
-
aiPromptPayload: {
|
|
1117
|
-
display: false,
|
|
1118
|
-
message: "",
|
|
1119
|
-
messageId: "",
|
|
1120
|
-
branchId: "",
|
|
1121
|
-
userId: request.userId,
|
|
1122
|
-
scriptId: "",
|
|
1123
|
-
scriptType: "",
|
|
1124
|
-
type: "logs",
|
|
1125
|
-
sessionId: "",
|
|
1126
|
-
licenseId: request.licenseId,
|
|
1127
|
-
projectId: request.projectId,
|
|
1128
|
-
liveLogs: {
|
|
1129
|
-
executionId: request.kafkaMessageKey,
|
|
1130
|
-
message: errorInfo.errorDescription ?? "errorDescription unknown",
|
|
1131
|
-
messageType: messageType_js_1.MessageType.LiveLog.Error,
|
|
1132
|
-
},
|
|
1133
|
-
attachment: [],
|
|
1134
|
-
},
|
|
1135
|
-
}
|
|
1136
|
-
});
|
|
1137
|
-
logData_js_1.logger.info(`Message produced to Kafka topic - ${JSON.stringify({ messageType: messageType_js_1.MessageType.LiveLog.Error })}`);
|
|
1138
|
-
await context.scriptAppender.waitForAllSteps();
|
|
1139
|
-
if (driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey]) {
|
|
1140
|
-
driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey].push(...context.scriptAppender.getData());
|
|
1141
|
-
}
|
|
1142
|
-
else {
|
|
1143
|
-
driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey] = context.scriptAppender.getData();
|
|
1144
|
-
}
|
|
1145
|
-
context.scriptAppender.reset();
|
|
647
|
+
if (errorInfo && Object.keys(errorInfo).length > 0) {
|
|
648
|
+
await reporter.sendError(errorInfo.errorDescription);
|
|
649
|
+
await this.saveSessionStepData(context, request.kafkaMessageKey);
|
|
1146
650
|
return;
|
|
1147
651
|
}
|
|
1148
652
|
else {
|
|
1149
653
|
if (request?.aiExecutionAction === "stopExecution") {
|
|
1150
|
-
await
|
|
1151
|
-
topic: this.KafkaPayload.topic, message: {
|
|
1152
|
-
topic: "",
|
|
1153
|
-
service: "",
|
|
1154
|
-
chatId: "",
|
|
1155
|
-
aiPromptPayload: {
|
|
1156
|
-
display: false,
|
|
1157
|
-
message: "",
|
|
1158
|
-
messageId: "",
|
|
1159
|
-
branchId: "",
|
|
1160
|
-
userId: request.userId,
|
|
1161
|
-
scriptId: "",
|
|
1162
|
-
scriptType: "",
|
|
1163
|
-
type: "logs",
|
|
1164
|
-
sessionId: "",
|
|
1165
|
-
licenseId: request.licenseId,
|
|
1166
|
-
projectId: request.projectId,
|
|
1167
|
-
liveLogs: {
|
|
1168
|
-
executionId: request.kafkaMessageKey,
|
|
1169
|
-
message: "Execution stopped",
|
|
1170
|
-
messageType: messageType_js_1.MessageType.LiveLog.ExecutionStopped,
|
|
1171
|
-
},
|
|
1172
|
-
attachment: [],
|
|
1173
|
-
},
|
|
1174
|
-
}
|
|
1175
|
-
});
|
|
1176
|
-
logData_js_1.logger.info(`Message produced to Kafka topic - ${JSON.stringify({ messageType: messageType_js_1.MessageType.LiveLog.ExecutionStopped })}`);
|
|
654
|
+
await reporter.sendExecutionStopped();
|
|
1177
655
|
}
|
|
1178
656
|
else if (hasMoreSteps) {
|
|
1179
657
|
keepSessionAlive = true;
|
|
1180
|
-
await
|
|
1181
|
-
|
|
1182
|
-
topic: "",
|
|
1183
|
-
service: "",
|
|
1184
|
-
chatId: "",
|
|
1185
|
-
aiPromptPayload: {
|
|
1186
|
-
display: false,
|
|
1187
|
-
message: "",
|
|
1188
|
-
messageId: "",
|
|
1189
|
-
branchId: "",
|
|
1190
|
-
userId: request.userId,
|
|
1191
|
-
scriptId: "",
|
|
1192
|
-
scriptType: "",
|
|
1193
|
-
type: "logs",
|
|
1194
|
-
sessionId: "",
|
|
1195
|
-
licenseId: request.licenseId,
|
|
1196
|
-
projectId: request.projectId,
|
|
1197
|
-
liveLogs: {
|
|
1198
|
-
executionId: request.kafkaMessageKey,
|
|
1199
|
-
message: "Invoke the generate_script_from_scenario tool with the remaining test steps to continue the automation execution from where it left off.",
|
|
1200
|
-
messageType: messageType_js_1.MessageType.nextBatch,
|
|
1201
|
-
},
|
|
1202
|
-
attachment: [],
|
|
1203
|
-
},
|
|
1204
|
-
}
|
|
1205
|
-
});
|
|
1206
|
-
logData_js_1.logger.info(`Message produced to Kafka topic - ${JSON.stringify({ messageType: messageType_js_1.MessageType.nextBatch })}`);
|
|
1207
|
-
await context.scriptAppender.waitForAllSteps();
|
|
1208
|
-
if (driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey]) {
|
|
1209
|
-
driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey].push(...context.scriptAppender.getData());
|
|
1210
|
-
}
|
|
1211
|
-
else {
|
|
1212
|
-
driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey] = context.scriptAppender.getData();
|
|
1213
|
-
}
|
|
1214
|
-
context.scriptAppender.reset();
|
|
658
|
+
await reporter.sendNextBatch();
|
|
659
|
+
await this.saveSessionStepData(context, request.kafkaMessageKey);
|
|
1215
660
|
}
|
|
1216
661
|
else {
|
|
1217
|
-
await
|
|
1218
|
-
|
|
1219
|
-
topic: "",
|
|
1220
|
-
service: "",
|
|
1221
|
-
chatId: "",
|
|
1222
|
-
aiPromptPayload: {
|
|
1223
|
-
display: false,
|
|
1224
|
-
message: "",
|
|
1225
|
-
messageId: "",
|
|
1226
|
-
branchId: "",
|
|
1227
|
-
userId: request.userId,
|
|
1228
|
-
scriptId: "",
|
|
1229
|
-
scriptType: "",
|
|
1230
|
-
type: "logs",
|
|
1231
|
-
sessionId: "",
|
|
1232
|
-
licenseId: request.licenseId,
|
|
1233
|
-
projectId: request.projectId,
|
|
1234
|
-
liveLogs: {
|
|
1235
|
-
executionId: request.kafkaMessageKey,
|
|
1236
|
-
message: "Execution completed",
|
|
1237
|
-
messageType: messageType_js_1.MessageType.LiveLog.Completed,
|
|
1238
|
-
},
|
|
1239
|
-
attachment: [],
|
|
1240
|
-
},
|
|
1241
|
-
}
|
|
1242
|
-
});
|
|
1243
|
-
logData_js_1.logger.info(`Message produced to Kafka topic - ${JSON.stringify({ messageType: messageType_js_1.MessageType.LiveLog.Completed })}`);
|
|
1244
|
-
await context.scriptAppender.waitForAllSteps();
|
|
1245
|
-
if (driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey]) {
|
|
1246
|
-
driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey].push(...context.scriptAppender.getData());
|
|
1247
|
-
}
|
|
1248
|
-
else {
|
|
1249
|
-
driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey] = context.scriptAppender.getData();
|
|
1250
|
-
}
|
|
1251
|
-
context.scriptAppender.reset();
|
|
662
|
+
await reporter.sendCompleted();
|
|
663
|
+
await this.saveSessionStepData(context, request.kafkaMessageKey);
|
|
1252
664
|
}
|
|
1253
665
|
// Intermediate batches must only emit nextBatch. Sending AutomationScriptMetaData
|
|
1254
666
|
// here races the chat consumer and is treated as a finished execution.
|
|
@@ -1259,50 +671,20 @@ class AutomationRunner {
|
|
|
1259
671
|
liveLogs: messageType_js_1.MessageType.AutomationScriptMetaData,
|
|
1260
672
|
stepData: driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey],
|
|
1261
673
|
serverHost: request.serverHost,
|
|
1262
|
-
messageType: messageType_js_1.MessageType.AutomationScriptMetaData
|
|
674
|
+
messageType: messageType_js_1.MessageType.AutomationScriptMetaData,
|
|
1263
675
|
};
|
|
1264
|
-
|
|
1265
|
-
await fireflinkServiceInstance.produceMessageToKafka(request.kafkaMessageKey, {
|
|
1266
|
-
topic: this.KafkaPayload.topic, message: {
|
|
1267
|
-
topic: "",
|
|
1268
|
-
service: "",
|
|
1269
|
-
chatId: "",
|
|
1270
|
-
aiPromptPayload: {
|
|
1271
|
-
display: false,
|
|
1272
|
-
message: "",
|
|
1273
|
-
messageId: "",
|
|
1274
|
-
branchId: "",
|
|
1275
|
-
userId: request.userId,
|
|
1276
|
-
scriptId: "",
|
|
1277
|
-
scriptType: "",
|
|
1278
|
-
type: "logs",
|
|
1279
|
-
sessionId: "",
|
|
1280
|
-
licenseId: request.licenseId,
|
|
1281
|
-
projectId: request.projectId,
|
|
1282
|
-
liveLogs: {
|
|
1283
|
-
executionId: request.kafkaMessageKey,
|
|
1284
|
-
message: this.KafkaPayload,
|
|
1285
|
-
messageType: messageType_js_1.MessageType.AutomationScriptMetaData,
|
|
1286
|
-
},
|
|
1287
|
-
attachment: [],
|
|
1288
|
-
},
|
|
1289
|
-
}
|
|
1290
|
-
});
|
|
676
|
+
await reporter.sendMetadata(this.KafkaPayload);
|
|
1291
677
|
const stepDataArr = this.KafkaPayload.message.stepData;
|
|
1292
678
|
const lastStep = Array.isArray(stepDataArr) && stepDataArr.length > 0
|
|
1293
679
|
? stepDataArr[stepDataArr.length - 1]
|
|
1294
680
|
: null;
|
|
1295
|
-
const closeStepNames = new Set([
|
|
1296
|
-
"CloseBrowser",
|
|
1297
|
-
"IOS_CloseApp",
|
|
1298
|
-
"MOB_CloseApp",
|
|
1299
|
-
]);
|
|
681
|
+
const closeStepNames = new Set(["CloseBrowser", "IOS_CloseApp", "MOB_CloseApp"]);
|
|
1300
682
|
if (lastStep && closeStepNames.has(lastStep.nlpName)) {
|
|
1301
683
|
SessionManager_js_1.SessionManager.remove(request);
|
|
1302
684
|
delete driverState_js_1.UserSessionAutomationTestCase[request.kafkaMessageKey];
|
|
1303
685
|
logData_js_1.logger.info("Deletion happened.");
|
|
1304
686
|
}
|
|
1305
|
-
logData_js_1.logger.info(`Final Message produced to
|
|
687
|
+
logData_js_1.logger.info(`Final Message produced to Kafka topic ${JSON.stringify(this.KafkaPayload, null, 2)} successfully.`);
|
|
1306
688
|
}
|
|
1307
689
|
else {
|
|
1308
690
|
logData_js_1.logger.info("nextBatch produced; session kept alive for remaining steps.");
|
|
@@ -1315,7 +697,7 @@ class AutomationRunner {
|
|
|
1315
697
|
}
|
|
1316
698
|
finally {
|
|
1317
699
|
if (!keepSessionAlive) {
|
|
1318
|
-
await this.cleanup(context, domInfo, extractedRelevantDom, stepProcessor, fireflinkServiceInstance, request,
|
|
700
|
+
await this.cleanup(context, domInfo, extractedRelevantDom, stepProcessor, stepsInputData, fireflinkServiceInstance, request, currentPlatform);
|
|
1319
701
|
}
|
|
1320
702
|
}
|
|
1321
703
|
}
|