ff-automationv2 1.0.0 → 2.0.1-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/bitbucket-pipelines.yml +20 -0
- package/eslint.config.ts +29 -29
- package/package.json +51 -51
- package/src/ai/llmcalls/decodeApiKey.ts +14 -14
- package/src/ai/llmcalls/llmAction.ts +89 -89
- package/src/ai/llmcalls/parseLlmOputput.ts +69 -69
- package/src/ai/llmprompts/systemPrompts/actionExtractorPrompt.ts +70 -70
- package/src/ai/llmprompts/systemPrompts/errorDescriptionPrompt.ts +23 -23
- package/src/ai/llmprompts/systemPrompts/fireflinkElementIndexExtactors.ts +198 -198
- package/src/ai/llmprompts/systemPrompts/userStoryToListPrompt.ts +24 -24
- package/src/ai/llmprompts/systemPrompts/visionPrompt.ts +28 -28
- package/src/automation/actions/executor.ts +74 -74
- package/src/automation/actions/interaction/enterInput.ts +27 -27
- package/src/automation/actions/interface/interactionActionInterface.ts +26 -26
- package/src/automation/actions/interface/navigationActionInterface.ts +21 -21
- package/src/automation/actions/interface/waitActionInterface.ts +5 -5
- package/src/automation/actions/navigation/getTitle.ts +8 -8
- package/src/automation/actions/navigation/goBack.ts +8 -8
- package/src/automation/actions/navigation/navigate.ts +9 -9
- package/src/automation/actions/navigation/refresh.ts +8 -8
- package/src/automation/actions/wait/wait.ts +9 -9
- package/src/automation/browserSession/initiateBrowserSession.ts +81 -81
- package/src/core/constants/supportedActions.ts +7 -7
- package/src/core/interfaces/StableDomInterface.ts +5 -5
- package/src/core/interfaces/actionInterface.ts +13 -13
- package/src/core/interfaces/automationRunnerInterface.ts +2 -2
- package/src/core/interfaces/browserCapabilitiesInterface.ts +4 -4
- package/src/core/interfaces/browserConfigurationInterface.ts +2 -2
- package/src/core/interfaces/domAnalysisInterface.ts +34 -34
- package/src/core/interfaces/executionDetails.ts +29 -29
- package/src/core/interfaces/fireflinkScriptPayloadInterface.ts +39 -39
- package/src/core/interfaces/llmConfigurationInterface.ts +2 -2
- package/src/core/interfaces/llmResponseInterface.ts +38 -38
- package/src/core/interfaces/promptInterface.ts +21 -21
- package/src/core/interfaces/scriptGenrationDataInterface.ts +16 -16
- package/src/core/interfaces/toolsInterface.ts +5 -5
- package/src/core/main/actionHandlerFactory.ts +86 -86
- package/src/core/main/executionContext.ts +18 -18
- package/src/core/main/runAutomationScript.ts +177 -177
- package/src/core/main/stepProcessor.ts +28 -28
- package/src/core/types/llmResponseType.ts +10 -10
- package/src/core/types/visionllmInputType.ts +4 -4
- package/src/domAnalysis/getRelaventElements.ts +24 -24
- package/src/domAnalysis/relativeElementsFromDom.ts +94 -94
- package/src/domAnalysis/searchBest.ts +159 -159
- package/src/domAnalysis/simplifyAndFlatten.ts +118 -118
- package/src/fireflinkData/fireflinkLocators/elementsFromHTML.ts +656 -656
- package/src/fireflinkData/fireflinkLocators/getListOfLocators.ts +31 -31
- package/src/fireflinkData/fireflinkLocators/typeList.ts +36 -36
- package/src/fireflinkData/fireflinkScript/scriptGenrationData.ts +30 -30
- package/src/index.ts +5 -5
- package/src/llmConfig/llmConfiguration.ts +26 -26
- package/src/service/fireflinkApi.service.ts +46 -46
- package/src/service/scriptRunner.service.ts +83 -83
- package/src/utils/DomExtraction/jsForAttributeInjection.ts +254 -254
- package/src/utils/javascript/jsFindElement.ts +161 -161
- package/src/utils/javascript/jsForShadowRoot.ts +216 -216
- package/src/utils/javascript/jsForToaster.ts +60 -60
- package/src/utils/logger/logData.ts +36 -36
- package/tsconfig.json +26 -26
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
type keywordExtractor = {
|
|
3
|
-
priorAndNextSteps: string[];
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
export async function keywordExtractor(
|
|
7
|
-
{ priorAndNextSteps }: keywordExtractor
|
|
8
|
-
): Promise<string> {
|
|
9
|
-
|
|
10
|
-
const allowedActions: string[] = [
|
|
11
|
-
"enter",
|
|
12
|
-
"wait",
|
|
13
|
-
"verify",
|
|
14
|
-
"scroll",
|
|
15
|
-
"navigate",
|
|
16
|
-
"click",
|
|
17
|
-
"maximize",
|
|
18
|
-
"get",
|
|
19
|
-
"upload",
|
|
20
|
-
"close",
|
|
21
|
-
"open",
|
|
22
|
-
"drag_and_drop",
|
|
23
|
-
"switch"
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
const prompt = `
|
|
27
|
-
You are an expert in Web application testing.
|
|
28
|
-
From the step: step, extract ONLY the meaningful keywords so that i can search for the element in the dom.
|
|
29
|
-
|
|
30
|
-
Rules:
|
|
31
|
-
- Only give response for the current step .
|
|
32
|
-
- understand the step and context from the ${JSON.stringify(priorAndNextSteps)} and keywords should be from step.
|
|
33
|
-
- 3 to 5 keywords maximum.
|
|
34
|
-
- If the step is about entering text or Uploading file, Should NOT include input value from the step into keywords.
|
|
35
|
-
- If the step has words like tag name audio, video, image, svg, checkbox etc, include them in the keywords.
|
|
36
|
-
- If icon is mentioned in step then 'svg' should add in keywords and for Upload action first keyword should be 'file'.
|
|
37
|
-
- First keyword should be from step. Next keywords must be distinct and based on element label meaning only.
|
|
38
|
-
- If keyword is two words, then create an additional keyword by combining them.
|
|
39
|
-
Example: "Sign In" → "Sign In", "SignIn"
|
|
40
|
-
- Keywords can be string or number.
|
|
41
|
-
- Do NOT include generic UI words or action words.
|
|
42
|
-
- Do NOT include status or technical words.
|
|
43
|
-
- If element label contains multiple words, keep them together as ONE keyword.
|
|
44
|
-
- element_name: extract name of the element from step.
|
|
45
|
-
Capitalize first letter.
|
|
46
|
-
If not mentioned, return action as element_name.
|
|
47
|
-
- action rules:
|
|
48
|
-
click, enter, wait, scroll, navigate, get, maximize, close, open,
|
|
49
|
-
upload, drag_and_drop, switch
|
|
50
|
-
- action must be one of ${JSON.stringify(allowedActions)}.
|
|
51
|
-
If not, return "0".
|
|
52
|
-
- For navigate:
|
|
53
|
-
- keywords must contain ONLY full URL
|
|
54
|
-
- element_name must be "URL"
|
|
55
|
-
- navigate allowed ONLY if step intent is purely navigation
|
|
56
|
-
- If verification intent exists, MUST return "verify"
|
|
57
|
-
|
|
58
|
-
Respond only with JSON using this format:
|
|
59
|
-
{
|
|
60
|
-
"keywords": [],
|
|
61
|
-
"elementName": "",
|
|
62
|
-
"elementType":""
|
|
63
|
-
"action": ""
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
No other text.
|
|
67
|
-
`;
|
|
68
|
-
|
|
69
|
-
return prompt;
|
|
70
|
-
}
|
|
1
|
+
|
|
2
|
+
type keywordExtractor = {
|
|
3
|
+
priorAndNextSteps: string[];
|
|
4
|
+
|
|
5
|
+
};
|
|
6
|
+
export async function keywordExtractor(
|
|
7
|
+
{ priorAndNextSteps }: keywordExtractor
|
|
8
|
+
): Promise<string> {
|
|
9
|
+
|
|
10
|
+
const allowedActions: string[] = [
|
|
11
|
+
"enter",
|
|
12
|
+
"wait",
|
|
13
|
+
"verify",
|
|
14
|
+
"scroll",
|
|
15
|
+
"navigate",
|
|
16
|
+
"click",
|
|
17
|
+
"maximize",
|
|
18
|
+
"get",
|
|
19
|
+
"upload",
|
|
20
|
+
"close",
|
|
21
|
+
"open",
|
|
22
|
+
"drag_and_drop",
|
|
23
|
+
"switch"
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const prompt = `
|
|
27
|
+
You are an expert in Web application testing.
|
|
28
|
+
From the step: step, extract ONLY the meaningful keywords so that i can search for the element in the dom.
|
|
29
|
+
|
|
30
|
+
Rules:
|
|
31
|
+
- Only give response for the current step .
|
|
32
|
+
- understand the step and context from the ${JSON.stringify(priorAndNextSteps)} and keywords should be from step.
|
|
33
|
+
- 3 to 5 keywords maximum.
|
|
34
|
+
- If the step is about entering text or Uploading file, Should NOT include input value from the step into keywords.
|
|
35
|
+
- If the step has words like tag name audio, video, image, svg, checkbox etc, include them in the keywords.
|
|
36
|
+
- If icon is mentioned in step then 'svg' should add in keywords and for Upload action first keyword should be 'file'.
|
|
37
|
+
- First keyword should be from step. Next keywords must be distinct and based on element label meaning only.
|
|
38
|
+
- If keyword is two words, then create an additional keyword by combining them.
|
|
39
|
+
Example: "Sign In" → "Sign In", "SignIn"
|
|
40
|
+
- Keywords can be string or number.
|
|
41
|
+
- Do NOT include generic UI words or action words.
|
|
42
|
+
- Do NOT include status or technical words.
|
|
43
|
+
- If element label contains multiple words, keep them together as ONE keyword.
|
|
44
|
+
- element_name: extract name of the element from step.
|
|
45
|
+
Capitalize first letter.
|
|
46
|
+
If not mentioned, return action as element_name.
|
|
47
|
+
- action rules:
|
|
48
|
+
click, enter, wait, scroll, navigate, get, maximize, close, open,
|
|
49
|
+
upload, drag_and_drop, switch
|
|
50
|
+
- action must be one of ${JSON.stringify(allowedActions)}.
|
|
51
|
+
If not, return "0".
|
|
52
|
+
- For navigate:
|
|
53
|
+
- keywords must contain ONLY full URL
|
|
54
|
+
- element_name must be "URL"
|
|
55
|
+
- navigate allowed ONLY if step intent is purely navigation
|
|
56
|
+
- If verification intent exists, MUST return "verify"
|
|
57
|
+
|
|
58
|
+
Respond only with JSON using this format:
|
|
59
|
+
{
|
|
60
|
+
"keywords": [],
|
|
61
|
+
"elementName": "",
|
|
62
|
+
"elementType":""
|
|
63
|
+
"action": ""
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
No other text.
|
|
67
|
+
`;
|
|
68
|
+
|
|
69
|
+
return prompt;
|
|
70
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
export async function buildErrorDescriptionPrompt(): Promise<string> {
|
|
2
|
-
const description_prompt = `
|
|
3
|
-
|
|
4
|
-
Analyze the error and execution history to provide diagnostics in JSON format.
|
|
5
|
-
|
|
6
|
-
Return a JSON object with the following keys:
|
|
7
|
-
1. "error": A concise, single-line, selenium type(error).__name__ (e.g., "InvalidSessionIdException", "InvalidElementStateException", "ElementNotInteractableException", "NoSuchElementException" etc).
|
|
8
|
-
2. "errorDescription": A very simple, non-technical, and user-friendly explanation of why the automation might have failed.
|
|
9
|
-
- Use plain English.
|
|
10
|
-
- All the lines should contain FireFlink. example: "FireFlink was unable to find the element..."
|
|
11
|
-
- Do not mention code, XPaths, or internal technical terms.
|
|
12
|
-
- The output MUST be a single paragraph of exactly 10 to 15 lines of text.
|
|
13
|
-
- Focus on potential real-world causes.
|
|
14
|
-
|
|
15
|
-
Respond only with JSON using this format:
|
|
16
|
-
{
|
|
17
|
-
"error": ",
|
|
18
|
-
"errorDescription": "",
|
|
19
|
-
}
|
|
20
|
-
`;
|
|
21
|
-
|
|
22
|
-
return description_prompt;
|
|
23
|
-
}
|
|
1
|
+
export async function buildErrorDescriptionPrompt(): Promise<string> {
|
|
2
|
+
const description_prompt = `
|
|
3
|
+
|
|
4
|
+
Analyze the error and execution history to provide diagnostics in JSON format.
|
|
5
|
+
|
|
6
|
+
Return a JSON object with the following keys:
|
|
7
|
+
1. "error": A concise, single-line, selenium type(error).__name__ (e.g., "InvalidSessionIdException", "InvalidElementStateException", "ElementNotInteractableException", "NoSuchElementException" etc).
|
|
8
|
+
2. "errorDescription": A very simple, non-technical, and user-friendly explanation of why the automation might have failed.
|
|
9
|
+
- Use plain English.
|
|
10
|
+
- All the lines should contain FireFlink. example: "FireFlink was unable to find the element..."
|
|
11
|
+
- Do not mention code, XPaths, or internal technical terms.
|
|
12
|
+
- The output MUST be a single paragraph of exactly 10 to 15 lines of text.
|
|
13
|
+
- Focus on potential real-world causes.
|
|
14
|
+
|
|
15
|
+
Respond only with JSON using this format:
|
|
16
|
+
{
|
|
17
|
+
"error": ",
|
|
18
|
+
"errorDescription": "",
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
return description_prompt;
|
|
23
|
+
}
|
|
@@ -1,198 +1,198 @@
|
|
|
1
|
-
type FFInspectorArgs = {
|
|
2
|
-
stepAction: string;
|
|
3
|
-
extractedDomJson: string;
|
|
4
|
-
priorAndNextSteps: string[];
|
|
5
|
-
isAlert?: boolean;
|
|
6
|
-
isDrag?: boolean;
|
|
7
|
-
};
|
|
8
|
-
export async function ffInspectorNumExtractor({
|
|
9
|
-
stepAction,
|
|
10
|
-
extractedDomJson,
|
|
11
|
-
priorAndNextSteps,
|
|
12
|
-
isAlert = false,
|
|
13
|
-
isDrag = false,
|
|
14
|
-
}: FFInspectorArgs
|
|
15
|
-
): Promise<
|
|
16
|
-
string
|
|
17
|
-
> {
|
|
18
|
-
const clickActions = ["click", "doubleclick", "rightclick"];
|
|
19
|
-
const alertActions = [
|
|
20
|
-
"ClickOkOnAlertPopup",
|
|
21
|
-
"ClickCancelOnAlertPopup",
|
|
22
|
-
"EnterDataToAlert",
|
|
23
|
-
"GetTextPresentOnAlertPopup",
|
|
24
|
-
"VerifyAlertPopupIsDisplayed",
|
|
25
|
-
"VerifyAlertPopUpMessageContainsString",
|
|
26
|
-
"WaitTillAlertIsPresent",
|
|
27
|
-
"VerifyTextPresentOnAlertPopup"
|
|
28
|
-
];
|
|
29
|
-
const elementType = ["button", "link"]
|
|
30
|
-
|
|
31
|
-
let prompt;
|
|
32
|
-
|
|
33
|
-
// ---------------- ALERT ----------------
|
|
34
|
-
if (isAlert) {
|
|
35
|
-
prompt = `
|
|
36
|
-
You are given a Selenium test step that requires interaction with a browser alert popup.
|
|
37
|
-
|
|
38
|
-
Rules:
|
|
39
|
-
- if the alert requires entering text or verification comparison, extract that text.
|
|
40
|
-
- If no input is needed, set "input_text" to "None".
|
|
41
|
-
- If step verifies text presence → VerifyTextPresentOnAlertPopup.
|
|
42
|
-
- If step verifies text contains → VerifyAlertPopUpMessageContainsString.
|
|
43
|
-
- Do not add explanations or extra text.
|
|
44
|
-
- Return ONE action from this list only: ${JSON.stringify(alertActions)}.
|
|
45
|
-
- Output must be valid JSON.
|
|
46
|
-
Respond only with JSON using this format:
|
|
47
|
-
|
|
48
|
-
{
|
|
49
|
-
"action": x,
|
|
50
|
-
"input_text": "text to enter" | "None"
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// ---------------- DRAG & DROP ----------------
|
|
57
|
-
else if (isDrag) {
|
|
58
|
-
prompt = `
|
|
59
|
-
You are an intelligent assistant that extracts structured UI action data.
|
|
60
|
-
|
|
61
|
-
Given a structured UI JSON representation with uniquely identified elements
|
|
62
|
-
(ff-inspect values like Fire-Flink-1, Fire-Flink-2... in DOM order),
|
|
63
|
-
locate the most appropriate elements for a drag-and-drop action.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Rules:
|
|
68
|
-
- Step: for the given step
|
|
69
|
-
- Use the simplified JSON to find elements.
|
|
70
|
-
- Identify source (drag) and destination (drop).
|
|
71
|
-
- If not found, return Fire-Flink-0 for both.
|
|
72
|
-
- Extract element names from step if possible.
|
|
73
|
-
- Respond with JSON only.
|
|
74
|
-
Simplified JSON:
|
|
75
|
-
${extractedDomJson}
|
|
76
|
-
|
|
77
|
-
Respond only with JSON using this format:
|
|
78
|
-
{
|
|
79
|
-
"drag": "Fire-Flink-x",
|
|
80
|
-
"drop": "Fire-Flink-x",
|
|
81
|
-
"action": "Builtin_DragAndDropToElement",
|
|
82
|
-
"drag_element_name": "x",
|
|
83
|
-
"drop_element_name": "x"
|
|
84
|
-
}
|
|
85
|
-
`;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// ---------------- WAIT / SCROLL ----------------
|
|
89
|
-
else if (stepAction === "wait" || stepAction === "scroll") {
|
|
90
|
-
prompt = `
|
|
91
|
-
You are an intelligent assistant that extracts structured UI action data.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
Rules:
|
|
96
|
-
- Step: for the given step
|
|
97
|
-
- Use context from test steps: ${JSON.stringify(priorAndNextSteps)}
|
|
98
|
-
- Use simplified JSON to find best FF-inspect match.
|
|
99
|
-
- Choose closest semantic + DOM-distance match.
|
|
100
|
-
- Default direction is down.
|
|
101
|
-
- Action:
|
|
102
|
-
- scroll → extract num_of_scrolls & direction
|
|
103
|
-
- wait → extract wait time (number only)
|
|
104
|
-
- No nulls; use empty strings if needed.
|
|
105
|
-
- The element type should be from this list ${elementType}
|
|
106
|
-
|
|
107
|
-
Simplified JSON:
|
|
108
|
-
${extractedDomJson}
|
|
109
|
-
|
|
110
|
-
Return ONLY valid JSON:
|
|
111
|
-
{
|
|
112
|
-
"attribute_value": "Fire-Flink-x",
|
|
113
|
-
"action": "x",
|
|
114
|
-
"input_text": "seconds in Interger | input text",
|
|
115
|
-
"keyword": "x",
|
|
116
|
-
"num_of_scrolls": "0",
|
|
117
|
-
"direction": "down",
|
|
118
|
-
"elementType":"x"
|
|
119
|
-
}
|
|
120
|
-
`;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// ---------------- DEFAULT (CLICK / ENTER / UPLOAD etc.) ----------------
|
|
124
|
-
else {
|
|
125
|
-
prompt = `
|
|
126
|
-
You are a deterministic UI action extraction engine.
|
|
127
|
-
|
|
128
|
-
OBJECTIVE:
|
|
129
|
-
Identify the SINGLE best matching element from the Simplified JSON
|
|
130
|
-
for the given step and return structured automation data.
|
|
131
|
-
|
|
132
|
-
-----------------------------------------
|
|
133
|
-
|
|
134
|
-
CONTEXT STEPS:
|
|
135
|
-
${JSON.stringify(priorAndNextSteps)}
|
|
136
|
-
|
|
137
|
-
CLICK ACTION WORDS:
|
|
138
|
-
${JSON.stringify(clickActions)}
|
|
139
|
-
|
|
140
|
-
ALLOWED ELEMENT TYPES:
|
|
141
|
-
${elementType}
|
|
142
|
-
-----------------------------------------
|
|
143
|
-
|
|
144
|
-
CRITICAL MATCHING LOGIC:
|
|
145
|
-
|
|
146
|
-
1. First understand intent:
|
|
147
|
-
- click words → click
|
|
148
|
-
- enter/type/write → enter_text
|
|
149
|
-
- upload → upload
|
|
150
|
-
- drag_and_drop → drag_and_drop
|
|
151
|
-
|
|
152
|
-
2. For ENTER actions:
|
|
153
|
-
DO NOT pick first input blindly.
|
|
154
|
-
Score candidates using priority:
|
|
155
|
-
|
|
156
|
-
Priority Order:
|
|
157
|
-
(1) Exact label text match
|
|
158
|
-
(2) Placeholder match
|
|
159
|
-
(3) Name attribute semantic match
|
|
160
|
-
(4) ID semantic match
|
|
161
|
-
(5) type="email" if step contains "email"
|
|
162
|
-
(6) DOM sibling label relationship
|
|
163
|
-
|
|
164
|
-
Choose highest scoring match.
|
|
165
|
-
|
|
166
|
-
If NO strong semantic match → return:
|
|
167
|
-
attribute_value = "Fire-Flink-0"
|
|
168
|
-
|
|
169
|
-
3. For CLICK actions:
|
|
170
|
-
- Prefer exact text match
|
|
171
|
-
- If multiple, choose closest contextual match
|
|
172
|
-
- If icon + svg exists, prefer svg element
|
|
173
|
-
|
|
174
|
-
4. Never hallucinate.
|
|
175
|
-
5. Only use FF values from provided JSON.
|
|
176
|
-
6. No null values. Use empty string "".
|
|
177
|
-
7. Output must be valid JSON only.
|
|
178
|
-
|
|
179
|
-
-----------------------------------------
|
|
180
|
-
SIMPLIFIED JSON:
|
|
181
|
-
${extractedDomJson}
|
|
182
|
-
-----------------------------------------
|
|
183
|
-
|
|
184
|
-
Respond ONLY with JSON:
|
|
185
|
-
|
|
186
|
-
{
|
|
187
|
-
"attribute_value": "Fire-Flink-x",
|
|
188
|
-
"action": "click | enter | upload | drag_and_drop",
|
|
189
|
-
"input_text": "",
|
|
190
|
-
"keyword": "",
|
|
191
|
-
"num_of_scrolls": "0",
|
|
192
|
-
"direction": "down",
|
|
193
|
-
"elementType": ""
|
|
194
|
-
}
|
|
195
|
-
`;
|
|
196
|
-
}
|
|
197
|
-
return prompt;
|
|
198
|
-
}
|
|
1
|
+
type FFInspectorArgs = {
|
|
2
|
+
stepAction: string;
|
|
3
|
+
extractedDomJson: string;
|
|
4
|
+
priorAndNextSteps: string[];
|
|
5
|
+
isAlert?: boolean;
|
|
6
|
+
isDrag?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export async function ffInspectorNumExtractor({
|
|
9
|
+
stepAction,
|
|
10
|
+
extractedDomJson,
|
|
11
|
+
priorAndNextSteps,
|
|
12
|
+
isAlert = false,
|
|
13
|
+
isDrag = false,
|
|
14
|
+
}: FFInspectorArgs
|
|
15
|
+
): Promise<
|
|
16
|
+
string
|
|
17
|
+
> {
|
|
18
|
+
const clickActions = ["click", "doubleclick", "rightclick"];
|
|
19
|
+
const alertActions = [
|
|
20
|
+
"ClickOkOnAlertPopup",
|
|
21
|
+
"ClickCancelOnAlertPopup",
|
|
22
|
+
"EnterDataToAlert",
|
|
23
|
+
"GetTextPresentOnAlertPopup",
|
|
24
|
+
"VerifyAlertPopupIsDisplayed",
|
|
25
|
+
"VerifyAlertPopUpMessageContainsString",
|
|
26
|
+
"WaitTillAlertIsPresent",
|
|
27
|
+
"VerifyTextPresentOnAlertPopup"
|
|
28
|
+
];
|
|
29
|
+
const elementType = ["button", "link"]
|
|
30
|
+
|
|
31
|
+
let prompt;
|
|
32
|
+
|
|
33
|
+
// ---------------- ALERT ----------------
|
|
34
|
+
if (isAlert) {
|
|
35
|
+
prompt = `
|
|
36
|
+
You are given a Selenium test step that requires interaction with a browser alert popup.
|
|
37
|
+
|
|
38
|
+
Rules:
|
|
39
|
+
- if the alert requires entering text or verification comparison, extract that text.
|
|
40
|
+
- If no input is needed, set "input_text" to "None".
|
|
41
|
+
- If step verifies text presence → VerifyTextPresentOnAlertPopup.
|
|
42
|
+
- If step verifies text contains → VerifyAlertPopUpMessageContainsString.
|
|
43
|
+
- Do not add explanations or extra text.
|
|
44
|
+
- Return ONE action from this list only: ${JSON.stringify(alertActions)}.
|
|
45
|
+
- Output must be valid JSON.
|
|
46
|
+
Respond only with JSON using this format:
|
|
47
|
+
|
|
48
|
+
{
|
|
49
|
+
"action": x,
|
|
50
|
+
"input_text": "text to enter" | "None"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ---------------- DRAG & DROP ----------------
|
|
57
|
+
else if (isDrag) {
|
|
58
|
+
prompt = `
|
|
59
|
+
You are an intelligent assistant that extracts structured UI action data.
|
|
60
|
+
|
|
61
|
+
Given a structured UI JSON representation with uniquely identified elements
|
|
62
|
+
(ff-inspect values like Fire-Flink-1, Fire-Flink-2... in DOM order),
|
|
63
|
+
locate the most appropriate elements for a drag-and-drop action.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
Rules:
|
|
68
|
+
- Step: for the given step
|
|
69
|
+
- Use the simplified JSON to find elements.
|
|
70
|
+
- Identify source (drag) and destination (drop).
|
|
71
|
+
- If not found, return Fire-Flink-0 for both.
|
|
72
|
+
- Extract element names from step if possible.
|
|
73
|
+
- Respond with JSON only.
|
|
74
|
+
Simplified JSON:
|
|
75
|
+
${extractedDomJson}
|
|
76
|
+
|
|
77
|
+
Respond only with JSON using this format:
|
|
78
|
+
{
|
|
79
|
+
"drag": "Fire-Flink-x",
|
|
80
|
+
"drop": "Fire-Flink-x",
|
|
81
|
+
"action": "Builtin_DragAndDropToElement",
|
|
82
|
+
"drag_element_name": "x",
|
|
83
|
+
"drop_element_name": "x"
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ---------------- WAIT / SCROLL ----------------
|
|
89
|
+
else if (stepAction === "wait" || stepAction === "scroll") {
|
|
90
|
+
prompt = `
|
|
91
|
+
You are an intelligent assistant that extracts structured UI action data.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
Rules:
|
|
96
|
+
- Step: for the given step
|
|
97
|
+
- Use context from test steps: ${JSON.stringify(priorAndNextSteps)}
|
|
98
|
+
- Use simplified JSON to find best FF-inspect match.
|
|
99
|
+
- Choose closest semantic + DOM-distance match.
|
|
100
|
+
- Default direction is down.
|
|
101
|
+
- Action:
|
|
102
|
+
- scroll → extract num_of_scrolls & direction
|
|
103
|
+
- wait → extract wait time (number only)
|
|
104
|
+
- No nulls; use empty strings if needed.
|
|
105
|
+
- The element type should be from this list ${elementType}
|
|
106
|
+
|
|
107
|
+
Simplified JSON:
|
|
108
|
+
${extractedDomJson}
|
|
109
|
+
|
|
110
|
+
Return ONLY valid JSON:
|
|
111
|
+
{
|
|
112
|
+
"attribute_value": "Fire-Flink-x",
|
|
113
|
+
"action": "x",
|
|
114
|
+
"input_text": "seconds in Interger | input text",
|
|
115
|
+
"keyword": "x",
|
|
116
|
+
"num_of_scrolls": "0",
|
|
117
|
+
"direction": "down",
|
|
118
|
+
"elementType":"x"
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ---------------- DEFAULT (CLICK / ENTER / UPLOAD etc.) ----------------
|
|
124
|
+
else {
|
|
125
|
+
prompt = `
|
|
126
|
+
You are a deterministic UI action extraction engine.
|
|
127
|
+
|
|
128
|
+
OBJECTIVE:
|
|
129
|
+
Identify the SINGLE best matching element from the Simplified JSON
|
|
130
|
+
for the given step and return structured automation data.
|
|
131
|
+
|
|
132
|
+
-----------------------------------------
|
|
133
|
+
|
|
134
|
+
CONTEXT STEPS:
|
|
135
|
+
${JSON.stringify(priorAndNextSteps)}
|
|
136
|
+
|
|
137
|
+
CLICK ACTION WORDS:
|
|
138
|
+
${JSON.stringify(clickActions)}
|
|
139
|
+
|
|
140
|
+
ALLOWED ELEMENT TYPES:
|
|
141
|
+
${elementType}
|
|
142
|
+
-----------------------------------------
|
|
143
|
+
|
|
144
|
+
CRITICAL MATCHING LOGIC:
|
|
145
|
+
|
|
146
|
+
1. First understand intent:
|
|
147
|
+
- click words → click
|
|
148
|
+
- enter/type/write → enter_text
|
|
149
|
+
- upload → upload
|
|
150
|
+
- drag_and_drop → drag_and_drop
|
|
151
|
+
|
|
152
|
+
2. For ENTER actions:
|
|
153
|
+
DO NOT pick first input blindly.
|
|
154
|
+
Score candidates using priority:
|
|
155
|
+
|
|
156
|
+
Priority Order:
|
|
157
|
+
(1) Exact label text match
|
|
158
|
+
(2) Placeholder match
|
|
159
|
+
(3) Name attribute semantic match
|
|
160
|
+
(4) ID semantic match
|
|
161
|
+
(5) type="email" if step contains "email"
|
|
162
|
+
(6) DOM sibling label relationship
|
|
163
|
+
|
|
164
|
+
Choose highest scoring match.
|
|
165
|
+
|
|
166
|
+
If NO strong semantic match → return:
|
|
167
|
+
attribute_value = "Fire-Flink-0"
|
|
168
|
+
|
|
169
|
+
3. For CLICK actions:
|
|
170
|
+
- Prefer exact text match
|
|
171
|
+
- If multiple, choose closest contextual match
|
|
172
|
+
- If icon + svg exists, prefer svg element
|
|
173
|
+
|
|
174
|
+
4. Never hallucinate.
|
|
175
|
+
5. Only use FF values from provided JSON.
|
|
176
|
+
6. No null values. Use empty string "".
|
|
177
|
+
7. Output must be valid JSON only.
|
|
178
|
+
|
|
179
|
+
-----------------------------------------
|
|
180
|
+
SIMPLIFIED JSON:
|
|
181
|
+
${extractedDomJson}
|
|
182
|
+
-----------------------------------------
|
|
183
|
+
|
|
184
|
+
Respond ONLY with JSON:
|
|
185
|
+
|
|
186
|
+
{
|
|
187
|
+
"attribute_value": "Fire-Flink-x",
|
|
188
|
+
"action": "click | enter | upload | drag_and_drop",
|
|
189
|
+
"input_text": "",
|
|
190
|
+
"keyword": "",
|
|
191
|
+
"num_of_scrolls": "0",
|
|
192
|
+
"direction": "down",
|
|
193
|
+
"elementType": ""
|
|
194
|
+
}
|
|
195
|
+
`;
|
|
196
|
+
}
|
|
197
|
+
return prompt;
|
|
198
|
+
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
export async function buildStepExtractionPrompt(
|
|
3
|
-
): Promise<string> {
|
|
4
|
-
const prompt = `
|
|
5
|
-
You are a structured automation assistant. Your task is to extract step data from a provided user story for web automation.
|
|
6
|
-
|
|
7
|
-
Requirements
|
|
8
|
-
Each step must be a single string (not a tuple or any other data type).
|
|
9
|
-
Preserve the original wording of each step.
|
|
10
|
-
You may rewrite for clarity or formatting consistency only.
|
|
11
|
-
Do not add new steps.
|
|
12
|
-
Do not remove any existing steps.
|
|
13
|
-
Do not introduce additional actions.
|
|
14
|
-
Do not include the example list in the response.
|
|
15
|
-
Do not include any extra text, commentary, markdown, or code fences.
|
|
16
|
-
Output Format
|
|
17
|
-
|
|
18
|
-
Respond strictly in valid JSON using the following structure:
|
|
19
|
-
{
|
|
20
|
-
"manaulSteps": ["step 1", "step 2", "step 3"]
|
|
21
|
-
}
|
|
22
|
-
`;
|
|
23
|
-
return prompt;
|
|
24
|
-
}
|
|
1
|
+
|
|
2
|
+
export async function buildStepExtractionPrompt(
|
|
3
|
+
): Promise<string> {
|
|
4
|
+
const prompt = `
|
|
5
|
+
You are a structured automation assistant. Your task is to extract step data from a provided user story for web automation.
|
|
6
|
+
|
|
7
|
+
Requirements
|
|
8
|
+
Each step must be a single string (not a tuple or any other data type).
|
|
9
|
+
Preserve the original wording of each step.
|
|
10
|
+
You may rewrite for clarity or formatting consistency only.
|
|
11
|
+
Do not add new steps.
|
|
12
|
+
Do not remove any existing steps.
|
|
13
|
+
Do not introduce additional actions.
|
|
14
|
+
Do not include the example list in the response.
|
|
15
|
+
Do not include any extra text, commentary, markdown, or code fences.
|
|
16
|
+
Output Format
|
|
17
|
+
|
|
18
|
+
Respond strictly in valid JSON using the following structure:
|
|
19
|
+
{
|
|
20
|
+
"manaulSteps": ["step 1", "step 2", "step 3"]
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
return prompt;
|
|
24
|
+
}
|