ff-automationv2 2.2.18 โ†’ 2.2.21

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.
@@ -31,7 +31,7 @@ export class llmAction {
31
31
  async getLLMResponseText(system, user) {
32
32
  let attempt = 0;
33
33
  const MAX_RETRIES = 5;
34
- const startTime = new Date().getTime();
34
+ // const startTime = new Date().getTime()
35
35
  while (attempt < MAX_RETRIES) {
36
36
  attempt++;
37
37
  try {
@@ -49,7 +49,7 @@ export class llmAction {
49
49
  logger.error(`Invalid LLM output. Retrying (${attempt})`);
50
50
  continue;
51
51
  }
52
- logger.info("Time taken to get LLM response (Text):", Date.now() - startTime, "ms");
52
+ // logger.info("Time taken to get LLM response (Text):", Date.now() - startTime, "ms");
53
53
  return response;
54
54
  }
55
55
  catch (error) {
@@ -64,7 +64,7 @@ export class llmAction {
64
64
  async getLLMResponseWithVision(system, userPrompt) {
65
65
  let attempt = 0;
66
66
  const MAX_RETRIES = 5;
67
- const startTime = new Date().getTime();
67
+ // const startTime = new Date().getTime()
68
68
  while (attempt < MAX_RETRIES) {
69
69
  attempt++;
70
70
  try {
@@ -82,7 +82,7 @@ export class llmAction {
82
82
  logger.error(`Invalid Vision output. Retrying (${attempt})`);
83
83
  continue;
84
84
  }
85
- logger.info("Time taken to get LLM response (vision):", Date.now() - startTime, "ms");
85
+ // logger.info("Time taken to get LLM response (vision):", Date.now() - startTime, "ms");
86
86
  return response;
87
87
  }
88
88
  catch (error) {
@@ -1,4 +1,4 @@
1
- import { logger } from "../../utils/logger/logData.js";
1
+ // import { logger } from "../../utils/logger/logData.js";
2
2
  export class LLMResultParser {
3
3
  constructor() {
4
4
  this.inputTokens = 0;
@@ -19,11 +19,9 @@ export class LLMResultParser {
19
19
  }
20
20
  let parsedContent;
21
21
  try {
22
- // Try direct parse first
23
22
  parsedContent = JSON.parse(content);
24
23
  }
25
24
  catch {
26
- // If LLM added explanation text, extract JSON block
27
25
  const extracted = this.extractJsonObject(content);
28
26
  if (!extracted) {
29
27
  throw new Error("Could not extract valid JSON from LLM response");
@@ -31,13 +29,10 @@ export class LLMResultParser {
31
29
  parsedContent = extracted;
32
30
  }
33
31
  const usage = llmOutput?.usage ?? {};
34
- const inputTokens = Number(usage.prompt_tokens ?? 0);
35
- const outputTokens = Number(usage.completion_tokens ?? 0);
36
- const totalTokens = Number(usage.total_tokens ?? 0);
37
- this.inputTokens += inputTokens;
38
- this.outputTokens += outputTokens;
39
- this.totalTokens += totalTokens;
40
- logger.info(`Total tokens for this call is : ${usage.total_tokens}`);
32
+ this.inputTokens += Number(usage.prompt_tokens ?? 0);
33
+ this.outputTokens += Number(usage.completion_tokens ?? 0);
34
+ this.totalTokens += Number(usage.total_tokens ?? 0);
35
+ // logger.info(`Total tokens for this call is : ${usage.total_tokens}`);
41
36
  return { response: parsedContent };
42
37
  }
43
38
  catch (error) {
@@ -18,7 +18,7 @@ export interface AutomationRequest {
18
18
  licenseId: string;
19
19
  userId: string;
20
20
  projectType: string;
21
- serverData: any;
21
+ env: string;
22
22
  userName: string;
23
23
  serverHost: string;
24
24
  browser: BrowserConfig;
@@ -33,4 +33,5 @@ export interface AutomationRequest {
33
33
  isCloud?: boolean;
34
34
  capabilities?: Record<string, any>;
35
35
  cloudConfig?: CloudConfig;
36
+ serverData?: any;
36
37
  }
@@ -20,7 +20,7 @@ export interface IPayload {
20
20
  licenseId: string;
21
21
  userId: string;
22
22
  projectType: string;
23
- tokensConsumed: number;
23
+ tokensConsumed?: number;
24
24
  errorInfo?: IErrorInfo;
25
25
  }
26
26
  export interface IFireFlinkApiService {
@@ -82,12 +82,13 @@ export class AutomationRunner {
82
82
  async run(request) {
83
83
  const usedElementNames = [];
84
84
  initLogger(request.sessionPath);
85
+ logger.info("User Given Step", request.userStory);
85
86
  if (request.isTerminate)
86
87
  return AutomationRunner.updateSessionTerminationInfo(request.testCaseId);
87
88
  AutomationRunner.sessionTerminationDetails[request.testCaseId] = request.isTerminate;
88
89
  const apiService = new FireFlinkApiService();
89
90
  const fireflinkServiceInstance = new fireflinkService(apiService, request.broker, request.sslConfig);
90
- const instanceDetails = await fireflinkServiceInstance.runGetInstancesDetails(request.projectId, request.token, request.serverData);
91
+ const instanceDetails = await fireflinkServiceInstance.runGetInstancesDetails(request.projectId, request.token, request.serverHost);
91
92
  const aiInfo = getAiInstanceInfo(instanceDetails.responseObject);
92
93
  const context = new ExecutionContext(request);
93
94
  const configProvider = new ServiceProviderBaseUrlProvider();
@@ -559,17 +560,19 @@ export class AutomationRunner {
559
560
  };
560
561
  try {
561
562
  await context.scriptAppender.waitForAllSteps();
562
- logger.info(context.scriptAppender.getData(), payload);
563
- this.KafkaPayload.topic = `Topic-FIREFLINK-api-requests-${request.serverHost}`;
563
+ logger.info(context.scriptAppender.getData());
564
+ this.KafkaPayload.topic = `Topic-FIREFLINK-api-requests-${request.env}`;
564
565
  this.KafkaPayload.message = {
565
566
  ...payload,
566
567
  stepData: context.scriptAppender.getData(),
567
568
  serverHost: request.serverHost
568
569
  };
569
- logger.info(this.KafkaPayload);
570
+ delete payload.tokensConsumed;
571
+ logger.info({ ...payload, topic: this.KafkaPayload.topic });
570
572
  await fireflinkServiceInstance.produceMessageToKafka(this.KafkaPayload);
571
573
  }
572
574
  catch (error) {
575
+ logger.error("Failed to produce message :", logger.getError(error));
573
576
  throw new Error("Failed to produce message :", { cause: error });
574
577
  }
575
578
  finally {
@@ -3,6 +3,6 @@ export declare class fireflinkService implements IFireflinkService {
3
3
  private apiService;
4
4
  private kafkaProducer;
5
5
  constructor(apiService: IFireFlinkApiService, broker: string[], sslConfig: any);
6
- runGetInstancesDetails(projectId: string, token: string, serverData: string): Promise<any>;
6
+ runGetInstancesDetails(projectId: string, token: string, serverHost: string): Promise<any>;
7
7
  produceMessageToKafka(kafkaArgs: IKafkaPayload): Promise<void>;
8
8
  }
@@ -5,7 +5,7 @@ export class fireflinkService {
5
5
  this.apiService = apiService;
6
6
  this.kafkaProducer = new KafkaProducerService(broker, sslConfig);
7
7
  }
8
- async runGetInstancesDetails(projectId, token, serverData) {
8
+ async runGetInstancesDetails(projectId, token, serverHost) {
9
9
  const headers = {
10
10
  Accept: "*/*",
11
11
  "Accept-Language": "en-US,en;q=0.9",
@@ -13,7 +13,7 @@ export class fireflinkService {
13
13
  projectId: projectId || "",
14
14
  Authorization: `Bearer ${token}`,
15
15
  };
16
- const url = `${serverData}/project/optimize/v3/ai-service-provider/selected-instance?projectId=${projectId}`;
16
+ const url = `${serverHost}/project/optimize/v3/ai-service-provider/selected-instance?projectId=${projectId}`;
17
17
  try {
18
18
  const finalResult = await this.apiService.getInstancesDetailsApi(headers, url);
19
19
  if (finalResult) {
@@ -30,6 +30,6 @@ export class fireflinkService {
30
30
  }
31
31
  }
32
32
  async produceMessageToKafka(kafkaArgs) {
33
- this.kafkaProducer.produceMessage(kafkaArgs);
33
+ await this.kafkaProducer.produceMessage(kafkaArgs);
34
34
  }
35
35
  }
@@ -1,7 +1,5 @@
1
1
  import { Kafka, logLevel } from "kafkajs";
2
2
  import { logger } from "../../utils/logger/logData.js";
3
- import dotenv from "dotenv";
4
- dotenv.config();
5
3
  export class KafkaProducerService {
6
4
  constructor(brokers, sslConfig) {
7
5
  this.kafka = new Kafka({
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,85 @@
1
+ console.log(new Date().getTime());
2
+ import { AutomationRunner } from "../index.js";
3
+ import path from "path";
4
+ import fs from "fs";
5
+ const certPath = path.join("D:", "Bitbucket", "automationV2", "Certificates", "certificate.crt");
6
+ const ssl = {
7
+ ca: [fs.readFileSync(certPath, "utf-8")],
8
+ rejectUnauthorized: false,
9
+ };
10
+ const runner = new AutomationRunner();
11
+ console.log(new Date().getTime());
12
+ runner.run({
13
+ userStory: [
14
+ ["Open browser"],
15
+ ["Navigate to https://www.google.com/"],
16
+ ["Maximize the browser"],
17
+ // ["Navigate to https://www.google.com/"],
18
+ // ["Maximize the browser"],
19
+ // ["Navigate to https://www.google.com/"],
20
+ // ["Maximize the browser"],
21
+ // ["click on Gmail link"],
22
+ ["Close browser"],
23
+ // ["start iteration using 'Data1' Dataprovider"],
24
+ // ["enter 'startIteration1' in search field"],
25
+ // ["enter level-A in search field"],
26
+ // ["start iteration using 'Data1' Dataprovider"],
27
+ // ["enter 'startIteration1' in search field"],
28
+ // ["enter level-B in search field"],
29
+ // ["End iteration"],
30
+ // ["End iteration"],
31
+ // ["click on Gmail link"],
32
+ // ["Close browser"],
33
+ ],
34
+ platform: "web",
35
+ pageDetails: {
36
+ Web: {
37
+ pageId: "PAG73a7a0ad-c092-4351-8a93-68647f60e343",
38
+ pageName: "ai-Page"
39
+ }
40
+ },
41
+ sessionPath: path.join("D:", "Bitbucket", "automationV2"),
42
+ serverHost: "https://test3.fireflink.com",
43
+ // topic: "",
44
+ // serviceAccounts: "",
45
+ webSocketId: "",
46
+ generatedBy: "",
47
+ licenseType: "C-Professional",
48
+ licenseId: "LIC3985",
49
+ userId: "USR26935",
50
+ projectType: "Web",
51
+ browser: {
52
+ browserName: "Google Chrome",
53
+ },
54
+ broker: ["test3.fireflink.com:9092"],
55
+ sslConfig: ssl,
56
+ env: "test3",
57
+ version: "asdfg",
58
+ type: "sdfg",
59
+ scriptName: "url",
60
+ scriptType: "web",
61
+ projectId: "PJT1116",
62
+ testCaseId: "SCR1208",
63
+ promptId: "3f6e123c-8ec6-47c1-90e1-1a2f53b49251",
64
+ userName: "default-user",
65
+ appiumPort: 0,
66
+ platformVersion: "",
67
+ realDeviceId: "",
68
+ serverData: "",
69
+ isCloud: false,
70
+ cloudConfig: {
71
+ accessKey: "yfAa_w199cJge2Gezsgb2Jnu7hKdqER1tExY5kKvgSvXfi1lRUelFsbTFI5pMq7zQuwwNXXnsLTkjKhvWcKDWsUoGLi9KjUV6gbUNDhqj0jWYFyW9h_0LIDEg5qXigwZdqzQqAvWwHin3gBhzGndeROtixv_VFhnseGSWRAHTajZzE-Zl0d8BP6gl0TEBUfoNgqBtAQVDLP6wAQzPfcyjjGFsdHkXWeHFkKmA78D7rKlnNuN2WgjIUlhYheDRDeqZ98Ig_PyS1GbUvjwJ73L38sr_cD4Y9lrKyWJV-m5RmtKhmkqRM8uk5gEfjzgwy30",
72
+ hostname: "devicefarm.fireflink.com",
73
+ licenseId: "LIC2026658",
74
+ projectName: "Project-6",
75
+ protocol: "https",
76
+ path: "backend/fireflinkcloud/wd/hub"
77
+ },
78
+ capabilities: {
79
+ browserName: "chrome",
80
+ platformName: "Windows 11",
81
+ browserVersion: "146"
82
+ },
83
+ isTerminate: false,
84
+ token: "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJRUFRfTnFuMkxxdDVmN09tOElWaW53dUJlR3ZVUUVBUkdxZkFuRHJxZU9NIn0.eyJleHAiOjE3NzUyODczODQsImlhdCI6MTc3NTIwMDk4NCwianRpIjoib25ydHJvOjYzOTYzMjJkLTNlZWYtNDg1NC04NmUzLTdlNzBhNjY1ZjM0MSIsImlzcyI6Imh0dHA6Ly8xMDMuMTgyLjIxMC4yMjY6MzAxMDcvcmVhbG1zL0ZpcmVGbGluay10ZXN0MyIsImF1ZCI6InRhcmdldC1jbGllbnQiLCJzdWIiOiJmOmNhMzBmNDk3LTY1Y2YtNGU4Zi1iZGE3LTE0ZjM1NTNiYzZmNTpqYWlha2FzaEB5b3BtYWlsLmNvbSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImZsaW5rLXNlcnZpY2UiLCJzaWQiOiIxMDkzNTU4Yi0xMDY4LTQxM2MtYjhlNi0wMjE3NzQwODBjMjgiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsImN1cnJlbnRMaWNlbnNlSWQiOiJMSUMzOTg1IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJjdXJyZW50UHJpdmlsZWdlIjoiU3VwZXIgQWRtaW4iLCJmdWxsTmFtZSI6ImphaSIsImFjdGl2YXRpb25TdGF0dXMiOiJBQ1RJVkUiLCJwcml2aWxlZ2UiOiJTdXBlciBBZG1pbiIsImxpY2Vuc2VOYW1lIjoiRmlyZUZsaW5rIC0gTElDMzk4NSIsInByZWZlcnJlZF91c2VybmFtZSI6ImphaSIsInVzZXJOYW1lIjoiamFpYWthc2hAeW9wbWFpbC5jb20iLCJiaWxsaW5nQ3ljbGUiOiJRdWFydGVybHkiLCJpZCI6IlVTUjI2OTM1IiwibGljZW5zZUlkIjoiTElDMzk4NSIsImVtYWlsIjoiamFpYWthc2hAeW9wbWFpbC5jb20ifQ.NOa6gz1thU8Qh04dvJMwUvGo3FZVc_ZAMbHL0j0pg_wOkmshcd8LSua0RoFYbBw5LR2RjJhVBkiZ2zD6s28EqdUdMJwjFfx4QF9ol8ut1T6-ohI_-xtCy1wdzx-dJ7svVSc7zptEcYEMEnkGEPXhTIjB0iql-Ry5MM2CkjOQP5yPdO3W8Lua2kSQmXWwWfZJSSnem8foN4oG7uJ_4T8Yh8V69iI2Trsbdp5k8CXUxs42vI73KyX0qwzcL-B-X6o1DnOaNS6T6RI7t9kGq6WXW0Iu29EVdqQ3jVnkPbOFfvSdRYRCb9Uw4qZL2qUQK3V31Jqw6Rd-r1IjDmBcXogoTg"
85
+ });
@@ -1 +0,0 @@
1
- export {};
@@ -1,82 +1,87 @@
1
- import { remote } from 'webdriverio';
2
- import { encode } from '@toon-format/toon';
3
- import * as cheerio from 'cheerio';
4
- import fs from 'fs';
5
- import { encoding_for_model } from "@dqbd/tiktoken";
6
- // ๐Ÿ”„ HTML โ†’ JSON
7
- function htmlToJson(html) {
8
- const $ = cheerio.load(html);
9
- // ๐Ÿงน remove useless elements
10
- $('script, style, noscript, iframe').remove();
11
- function parseElement(elem, depth = 0) {
12
- if (!elem || depth > 6)
13
- return null;
14
- const node = {
15
- tag: elem.name,
16
- attrs: elem.attribs || {},
17
- children: [] // โœ… FIX
18
- };
19
- for (const child of elem.children || []) {
20
- if (child.type === 'text') {
21
- const text = child.data.trim();
22
- if (text) {
23
- node.children.push({ text });
24
- }
25
- }
26
- else if (child.type === 'tag') {
27
- const parsed = parseElement(child, depth + 1);
28
- if (parsed) {
29
- node.children.push(parsed);
30
- }
31
- }
32
- }
33
- return node;
34
- }
35
- return parseElement($('body')[0]);
36
- }
37
- // ๐Ÿš€ Main runner
38
- async function run() {
39
- const browser = await remote({
40
- capabilities: {
41
- browserName: 'chrome'
42
- }
43
- });
44
- try {
45
- // ๐ŸŒ Open Amazon
46
- await browser.url('https://www.amzon.in/');
47
- // โณ wait for search box
48
- const searchBox = await browser.$('#twotabsearchtextbox');
49
- await searchBox.waitForDisplayed({ timeout: 10000 });
50
- // ๐Ÿ“„ Get HTML
51
- const html = await browser.getPageSource();
52
- // ๐Ÿ”„ Convert HTML โ†’ JSON
53
- const json = htmlToJson(html);
54
- // ๐Ÿ”„ JSON โ†’ TOON
55
- const start = performance.now();
56
- const encoded = encode({ data: json });
57
- const end = performance.now();
58
- console.log('HTML :', html.length);
59
- console.log('json size:', JSON.stringify(json).length);
60
- console.log('Encoded length:', encoded.length);
61
- console.log(`Time taken: ${(end - start).toFixed(2)} ms`);
62
- // ๐Ÿ’พ Save outputs (optional but useful)
63
- fs.writeFileSync('output.json', JSON.stringify(json, null, 2));
64
- fs.writeFileSync('output.toon', encoded);
65
- const enc = encoding_for_model("gpt-4"); // closest available
66
- function countTokens(text) {
67
- return enc.encode(text).length;
68
- }
69
- const jsonString = JSON.stringify(json);
70
- console.log("Token JSON count:", countTokens(jsonString));
71
- const jsonStringencoded = JSON.stringify(encoded);
72
- console.log("Token TOON count:", countTokens(jsonStringencoded));
73
- }
74
- catch (err) {
75
- console.error(err);
76
- }
77
- finally {
78
- await browser.deleteSession();
79
- }
80
- }
81
- run();
82
- console.log("hi");
1
+ "use strict";
2
+ // import { remote } from 'webdriverio'
3
+ // import { encode } from '@toon-format/toon'
4
+ // import * as cheerio from 'cheerio'
5
+ // import fs from 'fs'
6
+ // import { Tokenizer } from "@huggingface/tokenizers"
7
+ // import { encoding_for_model } from "@dqbd/tiktoken"
8
+ // // ๐Ÿง  Define proper type (fixes "never" error)
9
+ // type NodeType = {
10
+ // tag?: string
11
+ // attrs?: Record<string, string>
12
+ // children?: NodeType[]
13
+ // text?: string
14
+ // }
15
+ // // ๐Ÿ”„ HTML โ†’ JSON
16
+ // function htmlToJson(html: string): NodeType | null {
17
+ // const $ = cheerio.load(html)
18
+ // // ๐Ÿงน remove useless elements
19
+ // $('script, style, noscript, iframe').remove()
20
+ // function parseElement(elem: any, depth = 0): NodeType | null {
21
+ // if (!elem || depth > 6) return null
22
+ // const node: NodeType = {
23
+ // tag: elem.name,
24
+ // attrs: elem.attribs || {},
25
+ // children: [] as NodeType[] // โœ… FIX
26
+ // }
27
+ // for (const child of elem.children || []) {
28
+ // if (child.type === 'text') {
29
+ // const text = child.data.trim()
30
+ // if (text) {
31
+ // node.children!.push({ text })
32
+ // }
33
+ // } else if (child.type === 'tag') {
34
+ // const parsed = parseElement(child, depth + 1)
35
+ // if (parsed) {
36
+ // node.children!.push(parsed)
37
+ // }
38
+ // }
39
+ // }
40
+ // return node
41
+ // }
42
+ // return parseElement($('body')[0])
43
+ // }
44
+ // // ๐Ÿš€ Main runner
45
+ // async function run() {
46
+ // const browser = await remote({
47
+ // capabilities: {
48
+ // browserName: 'chrome'
49
+ // }
50
+ // })
51
+ // try {
52
+ // // ๐ŸŒ Open Amazon
53
+ // await browser.url('https://www.amzon.in/')
54
+ // // โณ wait for search box
55
+ // const searchBox = await browser.$('#twotabsearchtextbox')
56
+ // await searchBox.waitForDisplayed({ timeout: 10000 })
57
+ // // ๐Ÿ“„ Get HTML
58
+ // const html = await browser.getPageSource()
59
+ // // ๐Ÿ”„ Convert HTML โ†’ JSON
60
+ // const json = htmlToJson(html)
61
+ // // ๐Ÿ”„ JSON โ†’ TOON
62
+ // const start = performance.now()
63
+ // const encoded = encode({ data: json })
64
+ // const end = performance.now()
65
+ // console.log('HTML :', html.length)
66
+ // console.log('json size:', JSON.stringify(json).length)
67
+ // console.log('Encoded length:', encoded.length)
68
+ // console.log(`Time taken: ${(end - start).toFixed(2)} ms`)
69
+ // // ๐Ÿ’พ Save outputs (optional but useful)
70
+ // fs.writeFileSync('output.json', JSON.stringify(json, null, 2))
71
+ // fs.writeFileSync('output.toon', encoded)
72
+ // const enc = encoding_for_model("gpt-4") // closest available
73
+ // function countTokens(text: string) {
74
+ // return enc.encode(text).length
75
+ // }
76
+ // const jsonString = JSON.stringify(json)
77
+ // console.log("Token JSON count:", countTokens(jsonString))
78
+ // const jsonStringencoded = JSON.stringify(encoded)
79
+ // console.log("Token TOON count:", countTokens(jsonStringencoded))
80
+ // } catch (err) {
81
+ // console.error(err)
82
+ // } finally {
83
+ // await browser.deleteSession()
84
+ // }
85
+ // }
86
+ // run()
87
+ // console.log("hi")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ff-automationv2",
3
- "version": "2.2.18",
3
+ "version": "2.2.21",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "This lib is used to automate the manual testcase",