ff-automationv2 2.2.35 → 2.2.36-beta.2
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/llmcalls/llmAction.js +6 -5
- package/dist/ai/llmprompts/llmPromptTypes/systemPromptTypes.d.ts +3 -0
- package/dist/ai/llmprompts/promptRegistry.js +4 -0
- package/dist/ai/llmprompts/systemPrompts/actionExtractorPrompt.js +133 -133
- package/dist/ai/llmprompts/systemPrompts/arithmeticPrompt.js +40 -40
- package/dist/ai/llmprompts/systemPrompts/fileVerifyActionExtractorPrompt.js +36 -36
- package/dist/ai/llmprompts/systemPrompts/fireflinkElementIndexExtractor_Mob.js +4 -4
- package/dist/ai/llmprompts/systemPrompts/getActionExtractorPrompt.js +51 -51
- package/dist/ai/llmprompts/systemPrompts/inputContextPrompt.js +49 -49
- package/dist/ai/llmprompts/systemPrompts/mobileKeywordExtractor.js +86 -86
- package/dist/ai/llmprompts/systemPrompts/multichannelKeywordExtractor.js +47 -47
- package/dist/ai/llmprompts/systemPrompts/otpExtractorPrompt.js +16 -16
- package/dist/ai/llmprompts/systemPrompts/sliderSwipeVisionPrompt.d.ts +2 -0
- package/dist/ai/llmprompts/systemPrompts/sliderSwipeVisionPrompt.js +54 -0
- package/dist/ai/llmprompts/systemPrompts/verifyActionExtractorPromptMob.js +43 -43
- package/dist/ai/llmprompts/userPrompts/userPrompt.js +21 -0
- package/dist/automation/actions/executor.d.ts +1 -0
- package/dist/automation/actions/executor.js +23 -0
- package/dist/automation/actions/interaction/swipe/slider_Swipe.d.ts +2 -0
- package/dist/automation/actions/interaction/swipe/slider_Swipe.js +129 -0
- package/dist/automation/actions/interface/FireFlinkResponseSchema.d.ts +6 -0
- package/dist/automation/actions/interface/FireFlinkResponseSchema.js +8 -1
- package/dist/automation/actions/interface/swipeActionInterface.d.ts +15 -0
- package/dist/core/helpers/mobileSwipeHelper.d.ts +3 -0
- package/dist/core/helpers/mobileSwipeHelper.js +78 -0
- package/dist/core/helpers/visionFallbackHandler.js +5 -3
- package/dist/core/interfaces/actionInterface.d.ts +1 -0
- package/dist/core/interfaces/mobileSwipeSliderInterface.d.ts +25 -0
- package/dist/core/interfaces/mobileSwipeSliderInterface.js +2 -0
- package/dist/core/interfaces/promptInterface.d.ts +4 -0
- package/dist/core/main/actionHandlerFactory.js +2 -2
- package/dist/core/main/runAutomationScript.js +44 -1
- package/dist/core/types/promptType.d.ts +1 -0
- package/dist/core/types/promptType.js +1 -0
- package/dist/domAnalysis/searchBest.js +0 -1
- package/dist/utils/DomExtraction/jsForAttributeInjection.js +232 -232
- package/dist/utils/helpers/xpathcreation.js +18 -2
- package/package.json +91 -91
- package/dist/tests/Framework.d.ts +0 -0
- package/dist/tests/Framework.js +0 -62
- package/dist/tests/itertaion.d.ts +0 -1
- package/dist/tests/itertaion.js +0 -43
- package/dist/tests/multiBrowser.d.ts +0 -1
- package/dist/tests/multiBrowser.js +0 -34
- package/dist/tests/poc.d.ts +0 -0
- package/dist/tests/poc.js +0 -212
- package/dist/tests/senario.d.ts +0 -0
- package/dist/tests/senario.js +0 -1120
- package/dist/tests/start_iteration_suggestion.d.ts +0 -6
- package/dist/tests/start_iteration_suggestion.js +0 -46
- package/dist/tests/test.d.ts +0 -1
- package/dist/tests/test.js +0 -26
- package/dist/tests/test1.d.ts +0 -1
- package/dist/tests/test1.js +0 -30
- package/dist/tests/test12.d.ts +0 -1
- package/dist/tests/test12.js +0 -35
- package/dist/tests/test254.d.ts +0 -0
- package/dist/tests/test254.js +0 -87
- package/dist/tests/test3.d.ts +0 -1
- package/dist/tests/test3.js +0 -27
- package/dist/tests/testkaf.d.ts +0 -0
- package/dist/tests/testkaf.js +0 -52
- package/dist/tests/tests.data.d.ts +0 -1
- package/dist/tests/tests.data.js +0 -8
- package/dist/tests/testss.d.ts +0 -1
- package/dist/tests/testss.js +0 -23
- package/dist/tests/testwe.d.ts +0 -1
- package/dist/tests/testwe.js +0 -24
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.swipeVisionPrompt = swipeVisionPrompt;
|
|
4
|
+
async function swipeVisionPrompt({ priorAndNextSteps }) {
|
|
5
|
+
const prompt = `
|
|
6
|
+
You are a mobile automation assistant analyzing a swipe action from a screenshot.
|
|
7
|
+
|
|
8
|
+
Given:
|
|
9
|
+
- A screenshot with UI elements labeled using Fire-Flink indexes.
|
|
10
|
+
- The user's swipe step.
|
|
11
|
+
- Context: ${JSON.stringify(priorAndNextSteps)}.
|
|
12
|
+
|
|
13
|
+
Your first task is to identify the TARGET ELEMENT mentioned or implied by the user's step.
|
|
14
|
+
|
|
15
|
+
Then determine whether that exact target element is visually a SLIDER/DRAG CONTROL in the screenshot.
|
|
16
|
+
|
|
17
|
+
IMPORTANT:
|
|
18
|
+
- Return NormalSwipe=false ONLY if ALL conditions are true:
|
|
19
|
+
1. The target from the user's step is present in the screenshot.
|
|
20
|
+
2. The identified target corresponds to a specific UI control.
|
|
21
|
+
3. That control is visually designed to be dragged/slid from one position to another.
|
|
22
|
+
4. A parent/container defining the slider movement area can be identified.
|
|
23
|
+
- If the target is a normal text, button, link, image, icon, label, or any other non-slider element, return NormalSwipe=true.
|
|
24
|
+
- If the target exists but is NOT a slider/drag control, return NormalSwipe=true.
|
|
25
|
+
- If the target cannot be found, return NormalSwipe=true.
|
|
26
|
+
- Never classify an element as a slider only because the step contains words such as "swipe", "slide", "to", or because the element has a suitable size.
|
|
27
|
+
- Do not assume that any horizontally or vertically shaped element is a slider.
|
|
28
|
+
- The slider must have a clear visual indication that a specific control/thumb can be dragged.
|
|
29
|
+
- Do not use surrounding elements as the target unless they are actually the draggable control.
|
|
30
|
+
- For a valid slider, identify both:
|
|
31
|
+
- targetIndex = draggable thumb/control
|
|
32
|
+
- parentIndex = slider/container defining the movement boundary
|
|
33
|
+
- Determine the direction from the user's step and UI.
|
|
34
|
+
|
|
35
|
+
For a valid slider:
|
|
36
|
+
{
|
|
37
|
+
"NormalSwipe": false,
|
|
38
|
+
"parentIndex": "Fire-Flink-x",
|
|
39
|
+
"targetIndex": "Fire-Flink-x",
|
|
40
|
+
"direction": "left|right|up|down"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
For every other case:
|
|
44
|
+
{
|
|
45
|
+
"NormalSwipe": true,
|
|
46
|
+
"parentIndex": "Fire-Flink-0",
|
|
47
|
+
"targetIndex": "Fire-Flink-0",
|
|
48
|
+
"direction": "left|right|up|down|none"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Return ONLY valid JSON.
|
|
52
|
+
`.trim();
|
|
53
|
+
return prompt;
|
|
54
|
+
}
|
|
@@ -2,51 +2,51 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.verifyActionExtractorPromptMob = verifyActionExtractorPromptMob;
|
|
4
4
|
async function verifyActionExtractorPromptMob({ extractedDomJson, priorAndNextSteps, }) {
|
|
5
|
-
const nlpList = ` "MOB_VerifyElementIsDisplayed,MOB_VerifyElementIsDisabled,MOB_VerifyElementIsEnabled,MOB_VerifyElementIsSelected,MOB_VerifyText,MOB_VerifyAttributeValue,MOB_VerifyPartialAttributeValue,"
|
|
6
|
-
"MOB_VerifyElementIsDisplayedInSpecifiedTime,MOB_VerifyElementIsEnabledInSpecifiedTime,"
|
|
7
|
-
"MOB_VerifyBatteryLevel,MOB_VerifyPartialText,MOB_VerifyElementIsClickable,"
|
|
8
|
-
"MOB_VerifyIfKeyboardIsHidden,MOB_VerifyIfKeyboardIsShown,MOB_VerifyIfXAndYCoordinateOfElement,"
|
|
9
|
-
"MOB_VerifyHeightOfElement,MOB_VerifyXLocationOfAndroidElement,MOB_VerifyIfDeviceIsUnlocked,"
|
|
10
|
-
"MOB_VerifyIfWifiOff,MOB_VerifyElementIsSelectedInSpecifiedTime,MOB_VerifyIfWifiOn,MOB_VerifyIfDeviceIsLocked,"
|
|
11
|
-
"MOB_VerifyIfAirplaneModeOff,MOB_VerifyIfGpsOff,MOB_VerifyHexCodeForGivenXYCoordinates,"
|
|
12
|
-
"MOB_VerifyYLocationOfAndroidElement,MOB_VerifyIfGpsOn,MOB_VerifyIfAirplaneModeOn,"
|
|
13
|
-
"MOB_VerifyWidthOfElement,MOB_VerifyElementIsNotDisplayed,MOB_VerifyElementNotContainsText,"
|
|
5
|
+
const nlpList = ` "MOB_VerifyElementIsDisplayed,MOB_VerifyElementIsDisabled,MOB_VerifyElementIsEnabled,MOB_VerifyElementIsSelected,MOB_VerifyText,MOB_VerifyAttributeValue,MOB_VerifyPartialAttributeValue,"
|
|
6
|
+
"MOB_VerifyElementIsDisplayedInSpecifiedTime,MOB_VerifyElementIsEnabledInSpecifiedTime,"
|
|
7
|
+
"MOB_VerifyBatteryLevel,MOB_VerifyPartialText,MOB_VerifyElementIsClickable,"
|
|
8
|
+
"MOB_VerifyIfKeyboardIsHidden,MOB_VerifyIfKeyboardIsShown,MOB_VerifyIfXAndYCoordinateOfElement,"
|
|
9
|
+
"MOB_VerifyHeightOfElement,MOB_VerifyXLocationOfAndroidElement,MOB_VerifyIfDeviceIsUnlocked,"
|
|
10
|
+
"MOB_VerifyIfWifiOff,MOB_VerifyElementIsSelectedInSpecifiedTime,MOB_VerifyIfWifiOn,MOB_VerifyIfDeviceIsLocked,"
|
|
11
|
+
"MOB_VerifyIfAirplaneModeOff,MOB_VerifyIfGpsOff,MOB_VerifyHexCodeForGivenXYCoordinates,"
|
|
12
|
+
"MOB_VerifyYLocationOfAndroidElement,MOB_VerifyIfGpsOn,MOB_VerifyIfAirplaneModeOn,"
|
|
13
|
+
"MOB_VerifyWidthOfElement,MOB_VerifyElementIsNotDisplayed,MOB_VerifyElementNotContainsText,"
|
|
14
14
|
"MOB_VerifyIfAppIsClosed, MOB_CheckIfElementIsDisplayed"`;
|
|
15
15
|
const elementType = ["link", "textfield", "icon", "button", "radiobutton", "checkbox", "tab", "action overflow button", "hamburger menu", "toggle button", "steppers", "sliders"];
|
|
16
|
-
const prompt = `You are an intelligent assistant that extracts structured UI action data.
|
|
17
|
-
Given the step: step, the simplified DOM: ${extractedDomJson}, and the list of NLP names: ${nlpList}.
|
|
18
|
-
|
|
19
|
-
Select the perfect matching NLP name from the list that best fits the step's intent.
|
|
20
|
-
|
|
21
|
-
Return **only valid JSON** in the following format:
|
|
22
|
-
{
|
|
23
|
-
"attributeValue": "Fire-Flink-x",
|
|
24
|
-
"nlpName": "x",
|
|
25
|
-
"inputText":"x"
|
|
26
|
-
"elementType": "x",
|
|
27
|
-
"locatorType":"x"
|
|
28
|
-
}
|
|
29
|
-
Rules:
|
|
30
|
-
- nlpName must be exactly one from the provided list.
|
|
31
|
-
- Use context from the steps : ${priorAndNextSteps}, keyword and json to search for FF-inspecter.
|
|
32
|
-
- **Find the FF-inspecter attribute value of the element in the Simplified JSON whose text or attributes best match the step.**
|
|
33
|
-
- For some steps you can see two inputs but you need to uderstand step and send the requred inputText.
|
|
34
|
-
ex: Verify the flights matches the flight,Verify the home has 30 and 50 coordinates
|
|
35
|
-
here keyword : "flights" , input : flight, here input:30,50
|
|
36
|
-
- If step mention time and element name then inputText should be time.
|
|
37
|
-
example: Verify the home is displayed for 30 seconds
|
|
38
|
-
here keyword : "home" , input : 30 only they mention seconds as input in step
|
|
39
|
-
- If step mention verify text then only pick MOB_VerifyText nlp otherwise pick MOB_VerifyElementIsDisplayed.
|
|
40
|
-
- If step mention verify x and y coordinate of element then only pick MOB_VerifyIfXAndYCoordinateOfElement.
|
|
41
|
-
- Extract inputText from the step that is which is being verified in the step if they mention verifying two values in inputs take as it is,if they mention one value take only that as input text, if you can't find any input text in the step, return keyword as inputText.
|
|
42
|
-
- if the step is about checking the element is displayed then pick MOB_CheckIfElementIsDisplayed nlp.
|
|
43
|
-
- For MOB_VerifyHeightOfElement just provide height mentioned in the step as the inputText don't add anything else
|
|
44
|
-
- Extract keyword from the step, if the step contains any keyword.
|
|
45
|
-
- Use the closest semantic match for the step; return attributeValue as Fire-Flink-0, only if nothing is found.
|
|
46
|
-
- Based on step give most relevant type of element. use this list to choose elementType: ${elementType} and Never change syntax of elementType, follow the syntax of elementType in list.if elementType is not there in list return 'link'.
|
|
47
|
-
- Extract locator_type if mentioned in the step, like(text,resource-id,content-desc) . if not found return 'empty'.
|
|
48
|
-
- Return ONLY a valid JSON object; the response must start with '{' and end with '}', with no markdown, code fences, explanations, or extra text.
|
|
49
|
-
- Respond with valid JSON only.
|
|
16
|
+
const prompt = `You are an intelligent assistant that extracts structured UI action data.
|
|
17
|
+
Given the step: step, the simplified DOM: ${extractedDomJson}, and the list of NLP names: ${nlpList}.
|
|
18
|
+
|
|
19
|
+
Select the perfect matching NLP name from the list that best fits the step's intent.
|
|
20
|
+
|
|
21
|
+
Return **only valid JSON** in the following format:
|
|
22
|
+
{
|
|
23
|
+
"attributeValue": "Fire-Flink-x",
|
|
24
|
+
"nlpName": "x",
|
|
25
|
+
"inputText":"x"
|
|
26
|
+
"elementType": "x",
|
|
27
|
+
"locatorType":"x"
|
|
28
|
+
}
|
|
29
|
+
Rules:
|
|
30
|
+
- nlpName must be exactly one from the provided list.
|
|
31
|
+
- Use context from the steps : ${priorAndNextSteps}, keyword and json to search for FF-inspecter.
|
|
32
|
+
- **Find the FF-inspecter attribute value of the element in the Simplified JSON whose text or attributes best match the step.**
|
|
33
|
+
- For some steps you can see two inputs but you need to uderstand step and send the requred inputText.
|
|
34
|
+
ex: Verify the flights matches the flight,Verify the home has 30 and 50 coordinates
|
|
35
|
+
here keyword : "flights" , input : flight, here input:30,50
|
|
36
|
+
- If step mention time and element name then inputText should be time.
|
|
37
|
+
example: Verify the home is displayed for 30 seconds
|
|
38
|
+
here keyword : "home" , input : 30 only they mention seconds as input in step
|
|
39
|
+
- If step mention verify text then only pick MOB_VerifyText nlp otherwise pick MOB_VerifyElementIsDisplayed.
|
|
40
|
+
- If step mention verify x and y coordinate of element then only pick MOB_VerifyIfXAndYCoordinateOfElement.
|
|
41
|
+
- Extract inputText from the step that is which is being verified in the step if they mention verifying two values in inputs take as it is,if they mention one value take only that as input text, if you can't find any input text in the step, return keyword as inputText.
|
|
42
|
+
- if the step is about checking the element is displayed then pick MOB_CheckIfElementIsDisplayed nlp.
|
|
43
|
+
- For MOB_VerifyHeightOfElement just provide height mentioned in the step as the inputText don't add anything else
|
|
44
|
+
- Extract keyword from the step, if the step contains any keyword.
|
|
45
|
+
- Use the closest semantic match for the step; return attributeValue as Fire-Flink-0, only if nothing is found.
|
|
46
|
+
- Based on step give most relevant type of element. use this list to choose elementType: ${elementType} and Never change syntax of elementType, follow the syntax of elementType in list.if elementType is not there in list return 'link'.
|
|
47
|
+
- Extract locator_type if mentioned in the step, like(text,resource-id,content-desc) . if not found return 'empty'.
|
|
48
|
+
- Return ONLY a valid JSON object; the response must start with '{' and end with '}', with no markdown, code fences, explanations, or extra text.
|
|
49
|
+
- Respond with valid JSON only.
|
|
50
50
|
`;
|
|
51
51
|
return prompt;
|
|
52
52
|
}
|
|
@@ -38,4 +38,25 @@ exports.userInputFormatters = {
|
|
|
38
38
|
];
|
|
39
39
|
return content;
|
|
40
40
|
},
|
|
41
|
+
[promptType_js_1.PromptType.SWIPE_VISION_PROMPT]: (userInput) => {
|
|
42
|
+
let imageBase64 = null;
|
|
43
|
+
if (userInput.annotatedScreenshot) {
|
|
44
|
+
imageBase64 = (0, imageUtils_js_1.formatImageBase64)(userInput.annotatedScreenshot);
|
|
45
|
+
}
|
|
46
|
+
if (!imageBase64) {
|
|
47
|
+
throw new Error("Vision image is missing. No annotatedScreenshot provided.");
|
|
48
|
+
}
|
|
49
|
+
const content = [
|
|
50
|
+
{
|
|
51
|
+
type: "input_text",
|
|
52
|
+
text: `Analyze the following step for swipe action:\n\n${JSON.stringify(userInput.currentStep, null, 2)}`,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: "input_image",
|
|
56
|
+
image_url: imageBase64,
|
|
57
|
+
detail: "auto",
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
return content;
|
|
61
|
+
},
|
|
41
62
|
};
|
|
@@ -359,6 +359,7 @@ export declare class ActionExecutor implements IActionExecutor {
|
|
|
359
359
|
swipeRightToElement(value: string, elementName: string, elementType: string, numOfScrolls: number): Promise<void>;
|
|
360
360
|
swipeNTimes(numOfScrolls: string, direction?: string): Promise<void>;
|
|
361
361
|
swipeDirectionNTimes(numOfScrolls: string, direction: string): Promise<void>;
|
|
362
|
+
swipeSlider(parentXpath: string, targetXpath: string, direction?: string, elementName?: string, elementType?: string, parentIndex?: string, targetIndex?: string, pageDOM?: string): Promise<void>;
|
|
362
363
|
swipeToElementForMWeb(value: string, elementName: string, elementType: string, pageDOM: string, fireflinkIndex: string, numOfScrolls: number): Promise<void>;
|
|
363
364
|
swipeUsingReferenceElement(value: string, elementName: string, elementType: string, numOfScrolls: string, direction: string, pageDOM: string, fireflinkIndex: string): Promise<void>;
|
|
364
365
|
MOB_EnterInputIntoElementFromClipBoard(selector: string, elementName: string, elementType: string, pageDOM: string, fireflinkIndex: string): Promise<void>;
|
|
@@ -268,6 +268,7 @@ const swipeDownToElement_js_1 = require("./interaction/swipe/swipeDownToElement.
|
|
|
268
268
|
const swipeLeftToElement_js_1 = require("./interaction/swipe/swipeLeftToElement.js");
|
|
269
269
|
const swipeRightToElement_js_1 = require("./interaction/swipe/swipeRightToElement.js");
|
|
270
270
|
const swipeDirectionNTimes_js_1 = require("./interaction/swipe/swipeDirectionNTimes.js");
|
|
271
|
+
const slider_Swipe_js_1 = require("./interaction/swipe/slider_Swipe.js");
|
|
271
272
|
const swipeUsingReferenceElement_js_1 = require("./interaction/swipe/swipeUsingReferenceElement.js");
|
|
272
273
|
const swipeUpToElementForMWeb_js_1 = require("./interaction/swipe/swipeUpToElementForMWeb.js");
|
|
273
274
|
const EnterInputIntoElementFromClipBoardInterface_mob_js_1 = require("./interaction/enterActions/EnterInputIntoElementFromClipBoardInterface_mob.js");
|
|
@@ -6428,6 +6429,28 @@ class ActionExecutor {
|
|
|
6428
6429
|
throw error;
|
|
6429
6430
|
}
|
|
6430
6431
|
}
|
|
6432
|
+
async swipeSlider(parentXpath, targetXpath, direction, elementName, elementType, parentIndex, targetIndex, pageDOM) {
|
|
6433
|
+
try {
|
|
6434
|
+
await (0, slider_Swipe_js_1.swipeSlider)({
|
|
6435
|
+
driver: this.driver,
|
|
6436
|
+
parentXpath,
|
|
6437
|
+
targetXpath,
|
|
6438
|
+
direction,
|
|
6439
|
+
platform: this.platform,
|
|
6440
|
+
scriptDataAppender: this.scriptDataAppender,
|
|
6441
|
+
elementName,
|
|
6442
|
+
elementType,
|
|
6443
|
+
parentIndex,
|
|
6444
|
+
targetIndex,
|
|
6445
|
+
pageDOM,
|
|
6446
|
+
elementGetter: this.elementGetter
|
|
6447
|
+
});
|
|
6448
|
+
}
|
|
6449
|
+
catch (error) {
|
|
6450
|
+
logData_js_1.logger.error("Error in [ActionExecutor]", error);
|
|
6451
|
+
throw error;
|
|
6452
|
+
}
|
|
6453
|
+
}
|
|
6431
6454
|
async swipeToElementForMWeb(value, elementName, elementType, pageDOM, fireflinkIndex, numOfScrolls) {
|
|
6432
6455
|
try {
|
|
6433
6456
|
await (0, swipeUpToElementForMWeb_js_1.swipeUpToElementForMWeb)({
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.swipeSlider = swipeSlider;
|
|
4
|
+
const logData_js_1 = require("../../../../utils/logger/logData.js");
|
|
5
|
+
const appendScriptData_js_1 = require("../../../../fireflinkData/fireflinkScript/appendScriptData.js");
|
|
6
|
+
async function swipeSlider(args) {
|
|
7
|
+
const nlpName = args.platform === "ios"
|
|
8
|
+
? "IOS_Swipe"
|
|
9
|
+
: "MOB_SwipeNTimes";
|
|
10
|
+
try {
|
|
11
|
+
const parent = await args.driver.$(args.parentXpath);
|
|
12
|
+
const target = await args.driver.$(args.targetXpath);
|
|
13
|
+
if (!(await parent.isExisting())) {
|
|
14
|
+
throw new Error(`Slider parent not found: ${args.parentXpath}`);
|
|
15
|
+
}
|
|
16
|
+
if (!(await target.isExisting())) {
|
|
17
|
+
throw new Error(`Slider target not found: ${args.targetXpath}`);
|
|
18
|
+
}
|
|
19
|
+
const parentLocation = await parent.getLocation();
|
|
20
|
+
const parentSize = await parent.getSize();
|
|
21
|
+
const targetLocation = await target.getLocation();
|
|
22
|
+
const targetSize = await target.getSize();
|
|
23
|
+
const parentRect = {
|
|
24
|
+
x: parentLocation.x,
|
|
25
|
+
y: parentLocation.y,
|
|
26
|
+
width: parentSize.width,
|
|
27
|
+
height: parentSize.height
|
|
28
|
+
};
|
|
29
|
+
const targetRect = {
|
|
30
|
+
x: targetLocation.x,
|
|
31
|
+
y: targetLocation.y,
|
|
32
|
+
width: targetSize.width,
|
|
33
|
+
height: targetSize.height
|
|
34
|
+
};
|
|
35
|
+
const direction = (args.direction || "right")
|
|
36
|
+
.toLowerCase()
|
|
37
|
+
.trim();
|
|
38
|
+
let startX;
|
|
39
|
+
let startY;
|
|
40
|
+
let endX;
|
|
41
|
+
let endY;
|
|
42
|
+
switch (direction) {
|
|
43
|
+
case "right":
|
|
44
|
+
startX = targetRect.x + targetRect.width / 2;
|
|
45
|
+
startY = targetRect.y + targetRect.height / 2;
|
|
46
|
+
endX = parentRect.x + parentRect.width - 10;
|
|
47
|
+
endY = startY;
|
|
48
|
+
break;
|
|
49
|
+
case "left":
|
|
50
|
+
startX = targetRect.x + targetRect.width / 2;
|
|
51
|
+
startY = targetRect.y + targetRect.height / 2;
|
|
52
|
+
endX = parentRect.x + 10;
|
|
53
|
+
endY = startY;
|
|
54
|
+
break;
|
|
55
|
+
case "down":
|
|
56
|
+
startX = targetRect.x + targetRect.width / 2;
|
|
57
|
+
startY = targetRect.y + targetRect.height / 2;
|
|
58
|
+
endX = startX;
|
|
59
|
+
endY = parentRect.y + parentRect.height - 10;
|
|
60
|
+
break;
|
|
61
|
+
case "up":
|
|
62
|
+
startX = targetRect.x + targetRect.width / 2;
|
|
63
|
+
startY = targetRect.y + targetRect.height / 2;
|
|
64
|
+
endX = startX;
|
|
65
|
+
endY = parentRect.y + 10;
|
|
66
|
+
break;
|
|
67
|
+
default:
|
|
68
|
+
throw new Error(`Unsupported swipe direction: ${direction}`);
|
|
69
|
+
}
|
|
70
|
+
startX = Math.round(startX);
|
|
71
|
+
startY = Math.round(startY);
|
|
72
|
+
endX = Math.round(endX);
|
|
73
|
+
endY = Math.round(endY);
|
|
74
|
+
logData_js_1.logger.info(`Slider swipe: (${startX}, ${startY}) -> (${endX}, ${endY})`);
|
|
75
|
+
logData_js_1.logger.info(`direction = ${direction}`);
|
|
76
|
+
logData_js_1.logger.info(`startX = ${startX}`);
|
|
77
|
+
logData_js_1.logger.info(`startY = ${startY}`);
|
|
78
|
+
logData_js_1.logger.info(`endX = ${endX}`);
|
|
79
|
+
logData_js_1.logger.info(`endY = ${endY}`);
|
|
80
|
+
await args.driver.performActions([
|
|
81
|
+
{
|
|
82
|
+
type: "pointer",
|
|
83
|
+
id: "finger1",
|
|
84
|
+
parameters: {
|
|
85
|
+
pointerType: "touch"
|
|
86
|
+
},
|
|
87
|
+
actions: [
|
|
88
|
+
{
|
|
89
|
+
type: "pointerMove",
|
|
90
|
+
duration: 0,
|
|
91
|
+
x: startX,
|
|
92
|
+
y: startY
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
type: "pointerDown",
|
|
96
|
+
button: 0
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
type: "pause",
|
|
100
|
+
duration: 100
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
type: "pointerMove",
|
|
104
|
+
duration: 1000,
|
|
105
|
+
x: endX,
|
|
106
|
+
y: endY
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
type: "pointerUp",
|
|
110
|
+
button: 0
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
]);
|
|
115
|
+
await args.driver.releaseActions();
|
|
116
|
+
await args.driver.pause(1000);
|
|
117
|
+
const stepInputs = args.platform === "ios" ? [startX, startY, endX, endY] : [startX, startY, endX, endY, 1];
|
|
118
|
+
(0, appendScriptData_js_1.appendScriptData)({
|
|
119
|
+
scriptDataAppender: args.scriptDataAppender,
|
|
120
|
+
nlpName,
|
|
121
|
+
platform: args.platform,
|
|
122
|
+
stepInputs: stepInputs,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
args.scriptDataAppender.setErrorNLP(nlpName);
|
|
127
|
+
throw new Error("Slider swipe action failed", { cause: error });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -210,6 +210,12 @@ export declare const DefaultInteractionSchema: z.ZodObject<{
|
|
|
210
210
|
export declare const VisionSchema: z.ZodObject<{
|
|
211
211
|
fireflinkIndex: z.ZodString;
|
|
212
212
|
}, z.core.$strip>;
|
|
213
|
+
export declare const SwipeVisionSchema: z.ZodObject<{
|
|
214
|
+
NormalSwipe: z.ZodBoolean;
|
|
215
|
+
parentIndex: z.ZodString;
|
|
216
|
+
targetIndex: z.ZodString;
|
|
217
|
+
direction: z.ZodString;
|
|
218
|
+
}, z.core.$strip>;
|
|
213
219
|
export declare const UserStorySchema: z.ZodObject<{
|
|
214
220
|
manualSteps: z.ZodArray<z.ZodString>;
|
|
215
221
|
}, z.core.$strip>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ArithmeticSchema = exports.InputContextSchema = exports.OtpExtractorSchema = exports.ErrorDescriptionSchema = exports.UserStorySchema = exports.VisionSchema = exports.DefaultInteractionSchema = exports.MouseActionSchema = exports.UploadActionSchema = exports.GetOtpActionSchema = exports.ClearTextActionSchema = exports.EnterActionSchema = exports.TapActionSchema = exports.ClickActionSchema = exports.SwitchActionSchema = exports.MobileScrollSchema = exports.WebScrollSchema = exports.DragDropActionSchema = exports.MobileCombinedSchema = exports.CombinedActionSchema = exports.WaitActionSchema = exports.MobileGetSchema = exports.MobileFileVerifySchema = exports.MobileVerifySchema = exports.WebGetSchema = exports.WebFileVerifySchema = exports.WebVerifySchema = exports.AlertShema = exports.MultichannelKeywordSchema = exports.MultichannelStepItemSchema = exports.KeywordSchema = exports.StepItemSchema = void 0;
|
|
3
|
+
exports.ArithmeticSchema = exports.InputContextSchema = exports.OtpExtractorSchema = exports.ErrorDescriptionSchema = exports.UserStorySchema = exports.SwipeVisionSchema = exports.VisionSchema = exports.DefaultInteractionSchema = exports.MouseActionSchema = exports.UploadActionSchema = exports.GetOtpActionSchema = exports.ClearTextActionSchema = exports.EnterActionSchema = exports.TapActionSchema = exports.ClickActionSchema = exports.SwitchActionSchema = exports.MobileScrollSchema = exports.WebScrollSchema = exports.DragDropActionSchema = exports.MobileCombinedSchema = exports.CombinedActionSchema = exports.WaitActionSchema = exports.MobileGetSchema = exports.MobileFileVerifySchema = exports.MobileVerifySchema = exports.WebGetSchema = exports.WebFileVerifySchema = exports.WebVerifySchema = exports.AlertShema = exports.MultichannelKeywordSchema = exports.MultichannelStepItemSchema = exports.KeywordSchema = exports.StepItemSchema = void 0;
|
|
4
4
|
exports.getSchemaForPrompt = getSchemaForPrompt;
|
|
5
5
|
const zod_1 = require("zod");
|
|
6
6
|
const promptType_js_1 = require("../../../core/types/promptType.js");
|
|
@@ -183,6 +183,12 @@ exports.DefaultInteractionSchema = zod_1.z.object({
|
|
|
183
183
|
exports.VisionSchema = zod_1.z.object({
|
|
184
184
|
fireflinkIndex: zod_1.z.string(),
|
|
185
185
|
});
|
|
186
|
+
exports.SwipeVisionSchema = zod_1.z.object({
|
|
187
|
+
NormalSwipe: zod_1.z.boolean(),
|
|
188
|
+
parentIndex: zod_1.z.string(),
|
|
189
|
+
targetIndex: zod_1.z.string(),
|
|
190
|
+
direction: zod_1.z.string(),
|
|
191
|
+
});
|
|
186
192
|
exports.UserStorySchema = zod_1.z.object({
|
|
187
193
|
manualSteps: zod_1.z.array(zod_1.z.string()),
|
|
188
194
|
});
|
|
@@ -210,6 +216,7 @@ const schemaMap = {
|
|
|
210
216
|
[promptType_js_1.PromptType.KEYWORD_EXTRACTOR]: exports.KeywordSchema,
|
|
211
217
|
[promptType_js_1.PromptType.MULTICHANNEL_KEYWORD_EXTRACTOR]: exports.MultichannelKeywordSchema,
|
|
212
218
|
[promptType_js_1.PromptType.VISION_PROMPT]: exports.VisionSchema,
|
|
219
|
+
[promptType_js_1.PromptType.SWIPE_VISION_PROMPT]: exports.SwipeVisionSchema,
|
|
213
220
|
[promptType_js_1.PromptType.USER_STORY_TO_LIST]: exports.UserStorySchema,
|
|
214
221
|
[promptType_js_1.PromptType.ERROR_DESCRIPTION]: exports.ErrorDescriptionSchema,
|
|
215
222
|
[promptType_js_1.PromptType.WAIT_ACTION_EXTRACTOR_PROMPT]: exports.WaitActionSchema,
|
|
@@ -102,3 +102,18 @@ export interface swipe {
|
|
|
102
102
|
scriptDataAppender: ScriptDataAppender;
|
|
103
103
|
platform: string;
|
|
104
104
|
}
|
|
105
|
+
export interface swipeSliderI {
|
|
106
|
+
driver: WebdriverIO.Browser;
|
|
107
|
+
parentXpath: string;
|
|
108
|
+
targetXpath: string;
|
|
109
|
+
xpath?: string;
|
|
110
|
+
platform: string;
|
|
111
|
+
direction?: string;
|
|
112
|
+
scriptDataAppender: ScriptDataAppender;
|
|
113
|
+
elementName?: string;
|
|
114
|
+
elementType?: string;
|
|
115
|
+
parentIndex?: string;
|
|
116
|
+
targetIndex?: string;
|
|
117
|
+
elementGetter: ElementGetter;
|
|
118
|
+
pageDOM?: any;
|
|
119
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { MobileSwipeSliderParams, MobileSwipeSliderResult } from "../interfaces/mobileSwipeSliderInterface.js";
|
|
2
|
+
export { MobileSwipeSliderParams, MobileSwipeSliderResult };
|
|
3
|
+
export declare function checkMobileSwipeSlider(params: MobileSwipeSliderParams): Promise<MobileSwipeSliderResult>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkMobileSwipeSlider = checkMobileSwipeSlider;
|
|
4
|
+
const annotatedScreenshotMobile_js_1 = require("../../imageAnalysisMobile/annotatedScreenshotMobile.js");
|
|
5
|
+
const jsForAttributeInjection_js_1 = require("../../utils/DomExtraction/jsForAttributeInjection.js");
|
|
6
|
+
const promptType_js_1 = require("../types/promptType.js");
|
|
7
|
+
const xpathcreation_js_1 = require("../../utils/helpers/xpathcreation.js");
|
|
8
|
+
async function checkMobileSwipeSlider(params) {
|
|
9
|
+
const { driver, currentPlatform, stepAction, step, stepProcessor, priorAndNextSteps, } = params;
|
|
10
|
+
let domInfo = params.domInfo;
|
|
11
|
+
const doc = params.doc;
|
|
12
|
+
if (stepAction !== "MOB_SwipeToElement" || (currentPlatform !== "android" && currentPlatform !== "ios")) {
|
|
13
|
+
return { isSlider: false, domInfo, doc };
|
|
14
|
+
}
|
|
15
|
+
if (!domInfo?.dom) {
|
|
16
|
+
domInfo = await (0, jsForAttributeInjection_js_1.getAnnotatedDOMForMobile)(driver);
|
|
17
|
+
}
|
|
18
|
+
let visionAnnotationResult;
|
|
19
|
+
if (currentPlatform === "android") {
|
|
20
|
+
visionAnnotationResult = await (0, annotatedScreenshotMobile_js_1.annotateScreenshot)(driver, domInfo.dom);
|
|
21
|
+
}
|
|
22
|
+
else if (currentPlatform === "ios") {
|
|
23
|
+
visionAnnotationResult = await (0, annotatedScreenshotMobile_js_1.annotateIosScreenshot)(driver, domInfo.dom);
|
|
24
|
+
}
|
|
25
|
+
const stepResultVision = await stepProcessor.getLLMResponse({
|
|
26
|
+
platform: currentPlatform,
|
|
27
|
+
type: promptType_js_1.PromptType.SWIPE_VISION_PROMPT,
|
|
28
|
+
args: { priorAndNextSteps },
|
|
29
|
+
input: {
|
|
30
|
+
currentStep: step,
|
|
31
|
+
annotatedScreenshot: visionAnnotationResult?.boxedImageBuffer,
|
|
32
|
+
},
|
|
33
|
+
isVision: true,
|
|
34
|
+
});
|
|
35
|
+
const NormalSwipe = stepResultVision.response.NormalSwipe;
|
|
36
|
+
const parentIndex = stepResultVision.response.parentIndex || stepResultVision.response.fireflinkIndex;
|
|
37
|
+
const targetIndex = stepResultVision.response.targetIndex || stepResultVision.response.fireflinkIndex;
|
|
38
|
+
const direction = stepResultVision.response.direction?.toLowerCase()?.trim() || "right";
|
|
39
|
+
if (!NormalSwipe &&
|
|
40
|
+
parentIndex &&
|
|
41
|
+
targetIndex &&
|
|
42
|
+
parentIndex !== "Fire-Flink-0" &&
|
|
43
|
+
targetIndex !== "Fire-Flink-0") {
|
|
44
|
+
const bounds = visionAnnotationResult?.boxes;
|
|
45
|
+
const resolveBoundsAndXpath = (idxStr) => {
|
|
46
|
+
const idxNum = Number(idxStr.split("-").pop());
|
|
47
|
+
const box = bounds?.[idxNum - 1];
|
|
48
|
+
if (!box) {
|
|
49
|
+
throw new Error(`No bounds found for index ${idxStr} (${idxNum})`);
|
|
50
|
+
}
|
|
51
|
+
const { x1, y1, x2, y2 } = box;
|
|
52
|
+
const boundsStr = `[${x1},${y1}][${x2},${y2}]`;
|
|
53
|
+
const result = (0, xpathcreation_js_1.getFFIndexAndXPath)(domInfo.dom, boundsStr, currentPlatform);
|
|
54
|
+
if (!result.xpathPath) {
|
|
55
|
+
throw new Error(`Unable to resolve xpath for element ${idxStr}`);
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
xpath: result.xpathPath,
|
|
59
|
+
resolvedIndex: result.ffInspector ?? idxStr,
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
const parentResult = resolveBoundsAndXpath(parentIndex);
|
|
63
|
+
const targetResult = resolveBoundsAndXpath(targetIndex);
|
|
64
|
+
return {
|
|
65
|
+
isSlider: true,
|
|
66
|
+
parentXpath: parentResult.xpath,
|
|
67
|
+
targetXpath: targetResult.xpath,
|
|
68
|
+
sliderXpath: targetResult.xpath,
|
|
69
|
+
parentIndex: parentResult.resolvedIndex,
|
|
70
|
+
targetIndex: targetResult.resolvedIndex,
|
|
71
|
+
fireflinkIndex: targetResult.resolvedIndex,
|
|
72
|
+
direction,
|
|
73
|
+
domInfo,
|
|
74
|
+
doc,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return { isSlider: false, domInfo, doc };
|
|
78
|
+
}
|
|
@@ -73,7 +73,7 @@ async function executeVisionFallback(params) {
|
|
|
73
73
|
throw new Error(`vision unable to find element for step "${step}"`, { cause: causeError });
|
|
74
74
|
}
|
|
75
75
|
let xpath;
|
|
76
|
-
if ((platform === "android" || platform === "ios") && (driverContext
|
|
76
|
+
if ((platform === "android" || platform === "ios") && (!driverContext || fallbackAttempt < 2)) {
|
|
77
77
|
const index = Number(fireflinkIndex.split("-").pop());
|
|
78
78
|
const box = bounds[index - 1];
|
|
79
79
|
if (!box) {
|
|
@@ -99,10 +99,12 @@ async function executeVisionFallback(params) {
|
|
|
99
99
|
const result = (0, xpathcreation_js_1.getWebXPathByFFIndex)(domInfo.dom, fireflinkIndex);
|
|
100
100
|
xpath = result.xpathPath;
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
}
|
|
103
|
+
if (!xpath) {
|
|
104
|
+
if (platform === "web") {
|
|
103
105
|
context.scriptAppender.setErrorNLP(stepAction);
|
|
104
|
-
throw new Error(`Unable to resolve xpath for ${fireflinkIndex}`, { cause: causeError });
|
|
105
106
|
}
|
|
107
|
+
throw new Error(`Unable to resolve xpath for ${fireflinkIndex}`, { cause: causeError });
|
|
106
108
|
}
|
|
107
109
|
const pageDOM = iframeDomHtml ?? domInfo.dom;
|
|
108
110
|
const handler = actionHandlers[stepAction];
|
|
@@ -233,6 +233,7 @@ export interface IActionExecutor {
|
|
|
233
233
|
swipeRightToElement(value: string, elementName: string, elementType: string, nomOfScrolls?: number): Promise<void>;
|
|
234
234
|
swipeNTimes(nomOfScrolls: string, direction: string): Promise<void>;
|
|
235
235
|
swipeDirectionNTimes(nomOfScrolls: string, direction: string): Promise<void>;
|
|
236
|
+
swipeSlider(parentXpath: string, targetXpath: string, direction?: string, elementName?: string, elementType?: string, parentIndex?: string, targetIndex?: string, pageDOM?: string): Promise<void>;
|
|
236
237
|
swipeToElementForMWeb(value: string, elementName: string, elementType: string, pageDOM: string, fireflinkIndex: string, nomOfScrolls?: number): Promise<void>;
|
|
237
238
|
swipeUsingReferenceElement(value: string, elementName: string, elementType: string, nomOfScrolls: string, direction: string, pageDOM: string, fireflinkIndex: string): Promise<void>;
|
|
238
239
|
MOB_EnterInputIntoElementFromClipBoard(selector: string, elementName: string, elementType: string, pageDOM: string, fireflinkIndex: string): Promise<void>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { platform as PlatformType } from "../types/scriptTypesType.js";
|
|
2
|
+
export interface MobileSwipeSliderParams {
|
|
3
|
+
driver: any;
|
|
4
|
+
currentPlatform: PlatformType;
|
|
5
|
+
stepAction: string;
|
|
6
|
+
step: string;
|
|
7
|
+
domInfo: any;
|
|
8
|
+
doc: any;
|
|
9
|
+
stepProcessor: any;
|
|
10
|
+
priorAndNextSteps: string[];
|
|
11
|
+
fallbackAttempt: number;
|
|
12
|
+
driverContext?: any;
|
|
13
|
+
}
|
|
14
|
+
export interface MobileSwipeSliderResult {
|
|
15
|
+
isSlider: boolean;
|
|
16
|
+
parentXpath?: string;
|
|
17
|
+
targetXpath?: string;
|
|
18
|
+
sliderXpath?: string;
|
|
19
|
+
parentIndex?: string;
|
|
20
|
+
targetIndex?: string;
|
|
21
|
+
fireflinkIndex?: string;
|
|
22
|
+
direction?: string;
|
|
23
|
+
domInfo: any;
|
|
24
|
+
doc: any;
|
|
25
|
+
}
|
|
@@ -21,6 +21,10 @@ export interface PromptArgsMap {
|
|
|
21
21
|
currentStep: string;
|
|
22
22
|
priorAndNextSteps: string[];
|
|
23
23
|
};
|
|
24
|
+
[PromptType.SWIPE_VISION_PROMPT]: {
|
|
25
|
+
currentStep?: string;
|
|
26
|
+
priorAndNextSteps: string[];
|
|
27
|
+
};
|
|
24
28
|
[PromptType.VERIFY_PROMPT]: {
|
|
25
29
|
stepAction: string;
|
|
26
30
|
extractedDomJson: any;
|
|
@@ -1425,8 +1425,8 @@ function createActionHandlers(context) {
|
|
|
1425
1425
|
MOB_SwipeNTimes: withExecutor(async (executor, result) => {
|
|
1426
1426
|
await executor.swipeNTimes(result.numOfScrolls, result.direction);
|
|
1427
1427
|
}),
|
|
1428
|
-
|
|
1429
|
-
await executor.
|
|
1428
|
+
MOB_SwipeSlider: withExecutor(async (executor, result) => {
|
|
1429
|
+
await executor.swipeSlider(result.parentXpath || result.xpath || result.selector, result.targetXpath || result.xpath || result.selector, result.direction, result.elementName, result.elementType, result.parentIndex, result.targetIndex, result.pageDOM);
|
|
1430
1430
|
}),
|
|
1431
1431
|
MOB_SwipeDirectionNTimes: withExecutor(async (executor, result) => {
|
|
1432
1432
|
await executor.swipeDirectionNTimes(result.numOfScrolls, result.direction);
|