ff-automationv2 2.1.3-beta.2 → 2.1.3
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/package.json +1 -1
- package/src/ai/llmprompts/promptRegistry.ts +0 -2
- package/src/ai/llmprompts/userPrompts/userPrompt.ts +0 -4
- package/src/core/interfaces/promptInterface.ts +0 -5
- package/src/core/main/runAutomationScript.ts +22 -38
- package/src/core/types/promptType.ts +0 -1
- package/src/ai/llmprompts/systemPrompts/verifyActionExtractorPrompt.ts +0 -82
package/package.json
CHANGED
|
@@ -4,7 +4,6 @@ import { buildErrorDescriptionPrompt } from "./systemPrompts/errorDescriptionPro
|
|
|
4
4
|
import { ffInspectorNumExtractor } from "./systemPrompts/fireflinkElementIndexExtactors.js";
|
|
5
5
|
import { visionPrompt } from "./systemPrompts/visionPrompt.js";
|
|
6
6
|
import { PromptMap } from "../../core/types/promptMap.js";
|
|
7
|
-
import { verifyActionExtractorPrompt } from "./systemPrompts/verifyActionExtractorPrompt.js";
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
export const prompts: PromptMap = {
|
|
@@ -12,7 +11,6 @@ export const prompts: PromptMap = {
|
|
|
12
11
|
keywordExtractorPrompt: keywordExtractor,
|
|
13
12
|
errorDescriptionPrompt: buildErrorDescriptionPrompt,
|
|
14
13
|
ffInspectorNumExtractor: ffInspectorNumExtractor,
|
|
15
|
-
verifyActionExtractorPrompt: verifyActionExtractorPrompt,
|
|
16
14
|
visionPrompt: visionPrompt,
|
|
17
15
|
};
|
|
18
16
|
|
|
@@ -18,10 +18,6 @@ export const userInputFormatters: {
|
|
|
18
18
|
[PromptType.FF_INSPECTOR]: (userInput) =>
|
|
19
19
|
`Inspect the DOM for the following action context:\n\n${JSON.stringify(userInput.currentStep, null, 2)}`,
|
|
20
20
|
|
|
21
|
-
[PromptType.VERIFY_PROMPT]: (userInput) =>
|
|
22
|
-
`Inspect the DOM for the following verify context:\n\n${JSON.stringify(userInput.currentStep, null, 2)}`,
|
|
23
|
-
|
|
24
|
-
|
|
25
21
|
[PromptType.VISION_PROMPT]: (userInput) => {
|
|
26
22
|
const content: visionPromptMessage = [
|
|
27
23
|
{
|
|
@@ -99,17 +99,11 @@ export class AutomationRunner implements IAutomationRunner {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
logger.info(listOfSteps)
|
|
102
|
-
const allKeywordAction = ["enter", "wait", "verify", "scroll", "navigate", "click", "maximize", "get", "upload", "close", "open", "drag_and_drop", "switch", "cleartext"];
|
|
103
102
|
|
|
104
103
|
for (const step of listOfSteps) {
|
|
105
104
|
try {
|
|
106
105
|
if (AutomationRunner.getSessionTerminationInfo(this.request.testCaseId)) { break; }
|
|
107
106
|
|
|
108
|
-
logger.info
|
|
109
|
-
(
|
|
110
|
-
`Processing step ${stepCount}: "${step}"`
|
|
111
|
-
);
|
|
112
|
-
|
|
113
107
|
const start = Math.max(0, stepCount - 3);
|
|
114
108
|
const end = Math.min(listOfSteps.length, stepCount + 3);
|
|
115
109
|
const priorAndNextSteps = listOfSteps.slice(start, end);
|
|
@@ -123,13 +117,16 @@ export class AutomationRunner implements IAutomationRunner {
|
|
|
123
117
|
logger.info(JSON.stringify(result, null, 2))
|
|
124
118
|
|
|
125
119
|
const action = result.response.action?.toLowerCase();
|
|
120
|
+
const handler = actionHandlers[action];
|
|
126
121
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
let handler = actionHandlers[action];
|
|
122
|
+
logger.info
|
|
123
|
+
(
|
|
124
|
+
`Processing step ${stepCount}: "${step}" with action: "${action}" and keywords: ${JSON.stringify(result.response.keywords)}`
|
|
125
|
+
);
|
|
132
126
|
|
|
127
|
+
if (!handler) {
|
|
128
|
+
throw new Error(`Unsupported action: ${action}`);
|
|
129
|
+
}
|
|
133
130
|
|
|
134
131
|
if (INPUTLESS_ACTIONS.includes(action)) {
|
|
135
132
|
await handler(result);
|
|
@@ -137,7 +134,7 @@ export class AutomationRunner implements IAutomationRunner {
|
|
|
137
134
|
continue;
|
|
138
135
|
}
|
|
139
136
|
|
|
140
|
-
|
|
137
|
+
if (ELEMENTLESS_ACTION.includes(action)) {
|
|
141
138
|
const stepResult = await stepProcessor.getLLMResponse({
|
|
142
139
|
type: PromptType.FF_INSPECTOR,
|
|
143
140
|
args: {
|
|
@@ -154,6 +151,8 @@ export class AutomationRunner implements IAutomationRunner {
|
|
|
154
151
|
stepCount++;
|
|
155
152
|
continue;
|
|
156
153
|
}
|
|
154
|
+
|
|
155
|
+
|
|
157
156
|
const driver = await context.session.getCurrentBrowser();
|
|
158
157
|
domInfo = await getAnnotatedDOM(driver);
|
|
159
158
|
await logger.saveDOM(domInfo.dom, `annotated-dom-${stepCount}`);
|
|
@@ -166,29 +165,17 @@ export class AutomationRunner implements IAutomationRunner {
|
|
|
166
165
|
|
|
167
166
|
await logger.saveJSON(extractedRelevantDom, `relevant-dom-${stepCount}`);
|
|
168
167
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const stepResult = await stepProcessor.getLLMResponse({
|
|
181
|
-
type: PromptType.FF_INSPECTOR,
|
|
182
|
-
args: {
|
|
183
|
-
stepAction: action,
|
|
184
|
-
extractedDomJson: JSON.stringify(extractedRelevantDom, null, 2),
|
|
185
|
-
priorAndNextSteps,
|
|
186
|
-
isAlert: false,
|
|
187
|
-
isDrag: false
|
|
188
|
-
},
|
|
189
|
-
input: { currentStep: step }
|
|
190
|
-
});
|
|
191
|
-
}
|
|
168
|
+
const stepResult = await stepProcessor.getLLMResponse({
|
|
169
|
+
type: PromptType.FF_INSPECTOR,
|
|
170
|
+
args: {
|
|
171
|
+
stepAction: action,
|
|
172
|
+
extractedDomJson: JSON.stringify(extractedRelevantDom, null, 2),
|
|
173
|
+
priorAndNextSteps,
|
|
174
|
+
isAlert: false,
|
|
175
|
+
isDrag: false
|
|
176
|
+
},
|
|
177
|
+
input: { currentStep: step }
|
|
178
|
+
});
|
|
192
179
|
|
|
193
180
|
logger.info(JSON.stringify(stepResult, null, 2))
|
|
194
181
|
|
|
@@ -202,9 +189,6 @@ export class AutomationRunner implements IAutomationRunner {
|
|
|
202
189
|
throw new Error(`Unable to find element for ${step}`);
|
|
203
190
|
}
|
|
204
191
|
|
|
205
|
-
const stepAction = stepResult.response.action?.toLowerCase();
|
|
206
|
-
handler = actionHandlers[stepAction];
|
|
207
|
-
|
|
208
192
|
await handler({
|
|
209
193
|
selector: xpath,
|
|
210
194
|
value: stepResult.response.input_text,
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
type verifyActionArgs = {
|
|
2
|
-
extractedDomJson: string;
|
|
3
|
-
priorAndNextSteps: string[];
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export async function verifyActionExtractorPrompt({
|
|
7
|
-
extractedDomJson,
|
|
8
|
-
priorAndNextSteps,
|
|
9
|
-
|
|
10
|
-
}: verifyActionArgs
|
|
11
|
-
): Promise<string> {
|
|
12
|
-
const nlpList = `VerifyElementIsDisabled,VerifyElementIsEnabled,VerifyElementIsSelected,VerifyIfOptionWithIndexIsSelectedInListBox,VerifyWidthOfElement,VerifyBrowserWindowXLocation,
|
|
13
|
-
VerifyIfCookieNameIsDeleted,VerifyBrowserWindowWidth,VerifyValueOfElementIsCleared,
|
|
14
|
-
VerifyTagName,VerifyIfCookieNameIsAdded,VerifyLinkNavigatesToTitle,VerifyXLocationOfElement,
|
|
15
|
-
VerifyAllOptionsAreDeselected,VerifyBrowserHtmlCodeContainsString,VerifyBrowserWindowYLocation,
|
|
16
|
-
VerifyNumberOfElementsByTagName,VerifyListBoxOptionsAreSorted,VerifyNavigateURL,
|
|
17
|
-
VerifyHeightOfWebElement,VerifyValueOfElementContainsString,VerifyBrowserWindowHeight,
|
|
18
|
-
VerifyIfLinkIsBroken,VerifyValueOfElementIsString,VerifyYLocationOfElement,
|
|
19
|
-
VerifyNumberOfElementsByXpath,VerifyIfOptionWithIndexIsDeselectedInElement,VerifyAttributeValue,
|
|
20
|
-
VerifyElementIsDisplayed,VerifyAllOptionsAreSelected,VerifyIfOptionWithValueIsDeselected,
|
|
21
|
-
VerifyTitleOfCurrentPage,VerifyPartialTitleOfCurrentPage,VerifyElementIsNotDisplayed,
|
|
22
|
-
VerifyCssAttributeValue,VerifyPartialAttributeValue,VerifyIfSpecifiedOptionIsSelected,
|
|
23
|
-
VerifyTitleInAllPage,VerifyIfOptionWithValueIsSelected,VerifyIfVideoIsPlaying,
|
|
24
|
-
VerifyIfGivenOptionIsDuplicate,VerifyRadioButtonIsSelected,VerifyRadioButtonIsNotSelected,
|
|
25
|
-
VerifyThatSpecifiedOptionIsNotSelected,
|
|
26
|
-
VerifyText,VerifyPartialText,VerifyElementNotContainsText,VerifyElementIsClickable,
|
|
27
|
-
VerifyCheckBoxIsSelected,VerifyCheckBoxIsNotSelected,
|
|
28
|
-
VerifyUrlContainsExpectedUrl,VerifyUrlIsString,
|
|
29
|
-
VerifyBrowserWindowTitleContainsString,VerifyBrowserWindowTitleIsString,
|
|
30
|
-
VerifyIfBrowserWindowIsClosed,VerifyAllBrowserWindowsClosed,
|
|
31
|
-
VerifyIfAllCookiesAreDeleted,VerifyIfCookieObjectIsPresent,
|
|
32
|
-
VerifyIfXAndYCoordinateOfElement,VerifyIfVideoIsMuted,VerifyIfVideoIsPaused,
|
|
33
|
-
VerifyIfVideoEnded,VerifyIfVideoPlayingInMute,VerifyIfVideoPlayingInUnmute,
|
|
34
|
-
VerifyIfAudioIsPlaying,VerifyIfAudioIsPaused,VerifyIfAudioIsMuted,VerifyIfAudioEnded,
|
|
35
|
-
VerifyIfLinkIsWorking,VerifyIfLinksAreWorking,VerifyIfLinksAreBroken,
|
|
36
|
-
VerifyIfImageIsBroken,VerifyAllBrokenImages,VerifyIfStatusCodeOfALinkIsStatusCode,
|
|
37
|
-
VerifyIfStatusCodesOfLinks,VerifyIfOptionWithVisibleTextIsSelected,
|
|
38
|
-
VerifyIfOptionWithTextIsDeselected,VerifyPerformanceScore,VerifyAccessibilityScore,
|
|
39
|
-
VerifyBestPracticesScore,VerifySeoScore,VerifyPwaScore,VerifyHexCodeForGivenXYCoordinates`;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const elementType = ['link', 'textfield', 'icon', 'button', 'radioButton', 'text', 'textarea', 'image', 'dropdown', 'checkbox', 'tab', 'action overflow button', 'hamburger icon', 'toggle button', 'suggestion', 'time picker', 'date picker', 'toaster message', 'card', 'tooltip', 'option', 'calender', 'sliders', 'visual testing'];
|
|
43
|
-
const prompt = `You are an intelligent assistant that extracts structured UI action data.
|
|
44
|
-
Given the step, the simplified DOM: ${extractedDomJson}, and the list of NLP names: {nlp_list}.
|
|
45
|
-
|
|
46
|
-
Select the perfect matching NLP name from the list that best fits the step's intent.
|
|
47
|
-
**The NLP name must match exactly one value from the approved NLP list. Do not generate or suggest any new NLP names under any condition.**
|
|
48
|
-
step may give any way u need to get most matching and related nlp name from the list.
|
|
49
|
-
example: verify if email element is present
|
|
50
|
-
nlp name should be VerifyElementIsDisplayed
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
{
|
|
54
|
-
"attribute_value": "Fire-Flink-x",
|
|
55
|
-
"nlpName": "x",
|
|
56
|
-
"input_text":"x"
|
|
57
|
-
"keyword": "x",
|
|
58
|
-
"elementType": "x"
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
Rules:
|
|
62
|
-
- nlpName must be exactly one from the provided list.
|
|
63
|
-
- Use context from the steps : ${JSON.stringify(priorAndNextSteps)}, keyword and json to search for FF-inspecter.
|
|
64
|
-
- **Find the FF-inspecter attribute value of the element in the Simplified JSON whose text or attributes best match the step.**
|
|
65
|
-
- For some steps you can see two inputs but you need to understand step and send the required input_text. input_text can be string, number, url or xpath.
|
|
66
|
-
ex: Verify the flights matches the flight, Verify the home has 30 and 50 coordinates if they give x-30,y-50 just send 30,50 and verify hex code '#FFFFFF' for given (34,11) coordinates or they will give x-34,y-11 hexcode-#FFFFFF format than fill input_text in this order "#FFFFFF,34,11"
|
|
67
|
-
here keyword : "flights" , input : "flight", here input:"30,50" , here input:"#FFFFFF,34,11"
|
|
68
|
-
- If step is about checking value of attribute then map to attribute nlps and input_text: "attribute_name,element_name" here attribute_name can be id,text,href etc not fire-flink-x. input_text should be in this format.
|
|
69
|
-
and also If a step requires comparing two values, provide the input in the format input_text: "value1,value2".
|
|
70
|
-
- if step is about tag name then input_text: "tag name". and if step is about verifying tag name and with count then input_text: "tag name,count".
|
|
71
|
-
- if step is about verifying location then input_text: "coordinates".
|
|
72
|
-
- if step is about verifying options than map to option nlps.
|
|
73
|
-
- If a step involves a URL, map navigation/action keywords (navigate) to VerifyNavigateURL, partial match keywords (contains, includes) to VerifyUrlContainsExpectedUrl, exact match keywords (equals, is, exactly) to VerifyUrlIsString, default to exact match if unclear, and prioritize navigation if both intents exist.
|
|
74
|
-
- If no explicit option is mentioned in the step, map it to the most relevant non-option verification NLP based on the intent of the step.
|
|
75
|
-
- Extract input_text from the step that is which is being verified in the step, if you can't find any input text in the step, return keyword as input_text.
|
|
76
|
-
- Extract keyword from the step, if the step contains any keyword.
|
|
77
|
-
- Use the closest semantic match for the step; return attribute_value as Fire-Flink-0, only if nothing is found.
|
|
78
|
-
- Based on step give most relevant type of element. use this list to choose element_type: ${elementType} and Never change syntax of element_type, follow the syntax of element_type in list.if element_type is not there in list return 'link'.
|
|
79
|
-
- **Respond with valid JSON only. don't return any other text or don't return response in list format**
|
|
80
|
-
`;
|
|
81
|
-
return prompt;
|
|
82
|
-
}
|