@dev-blinq/cucumber_client 1.0.1691-dev → 1.0.1692-dev
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/bin/client/code_cleanup/utils.js +16 -7
- package/bin/client/code_gen/duplication_analysis.js +2 -1
- package/bin/client/code_gen/playwright_codeget.js +18 -9
- package/bin/client/cucumber/feature.js +4 -17
- package/bin/client/recorderv3/bvt_init.js +28 -86
- package/bin/client/recorderv3/bvt_recorder.js +12 -25
- package/bin/client/recorderv3/step_runner.js +2 -2
- package/bin/client/recorderv3/step_utils.js +30 -37
- package/bin/client/recorderv3/update_feature.js +45 -28
- package/bin/client/utils/app_dir.js +21 -0
- package/bin/client/utils/socket_logger.js +38 -14
- package/package.json +6 -2
- package/bin/client/recorderv3/app_dir.js +0 -23
- package/bin/client/recorderv3/network.js +0 -299
- package/bin/client/recorderv3/scriptTest.js +0 -5
- package/bin/client/recorderv3/ws_server.js +0 -72
|
@@ -10,7 +10,7 @@ import * as t from "@babel/types";
|
|
|
10
10
|
import { CucumberExpression, ParameterTypeRegistry } from "@cucumber/cucumber-expressions";
|
|
11
11
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
12
12
|
import { getAiConfig } from "../code_gen/page_reflection.js";
|
|
13
|
-
import socketLogger from "../utils/socket_logger.js";
|
|
13
|
+
import socketLogger, { getErrorMessage } from "../utils/socket_logger.js";
|
|
14
14
|
|
|
15
15
|
const STEP_KEYWORDS = new Set(["Given", "When", "Then"]);
|
|
16
16
|
|
|
@@ -308,18 +308,27 @@ export function getDefaultPrettierConfig() {
|
|
|
308
308
|
const configContent = readFileSync(prettierConfigPath, "utf-8");
|
|
309
309
|
prettierConfig = JSON.parse(configContent);
|
|
310
310
|
} catch (error) {
|
|
311
|
-
socketLogger.error(
|
|
312
|
-
|
|
311
|
+
socketLogger.error(
|
|
312
|
+
`Error parsing Prettier config file: ${getErrorMessage(error)}`,
|
|
313
|
+
undefined,
|
|
314
|
+
"getDefaultPrettierConfig"
|
|
315
|
+
);
|
|
313
316
|
}
|
|
314
317
|
} else {
|
|
315
318
|
// save the default config to .prettierrc
|
|
316
319
|
try {
|
|
317
320
|
writeFileSync(prettierConfigPath, JSON.stringify(prettierConfig, null, 2), "utf-8");
|
|
318
|
-
socketLogger.info(
|
|
319
|
-
|
|
321
|
+
socketLogger.info(
|
|
322
|
+
`Created default Prettier config at ${prettierConfigPath}`,
|
|
323
|
+
undefined,
|
|
324
|
+
"getDefaultPrettierConfig"
|
|
325
|
+
);
|
|
320
326
|
} catch (error) {
|
|
321
|
-
socketLogger.error(
|
|
322
|
-
|
|
327
|
+
socketLogger.error(
|
|
328
|
+
`Error writing Prettier config file: ${getErrorMessage(error)}`,
|
|
329
|
+
undefined,
|
|
330
|
+
"getDefaultPrettierConfig"
|
|
331
|
+
);
|
|
323
332
|
}
|
|
324
333
|
}
|
|
325
334
|
return prettierConfig;
|
|
@@ -4,6 +4,7 @@ import path from "path";
|
|
|
4
4
|
import { CodePage } from "./page_reflection.js";
|
|
5
5
|
import { compareElements, generateSignature } from "./function_signature.js";
|
|
6
6
|
import { updateStepDefinitions } from "../recorderv3/step_utils.js";
|
|
7
|
+
import socketLoggerInstance from "../utils/socket_logger.js";
|
|
7
8
|
/**
|
|
8
9
|
* DuplicationAnalizer class
|
|
9
10
|
* How to use:
|
|
@@ -101,7 +102,7 @@ async function compareWithScenario(projectDir, scenario) {
|
|
|
101
102
|
analyzerExisting.load();
|
|
102
103
|
// generate a temporary folder
|
|
103
104
|
const folder = fs.mkdtempSync(path.join(os.tmpdir(), "blinq-"));
|
|
104
|
-
await updateStepDefinitions({ scenario, featureName: "temp", projectDir: folder });
|
|
105
|
+
await updateStepDefinitions({ scenario, featureName: "temp", projectDir: folder, logger: socketLoggerInstance });
|
|
105
106
|
const analyzerScenario = new DuplicationAnalizer(folder);
|
|
106
107
|
analyzerScenario.load();
|
|
107
108
|
const compareResults = [];
|
|
@@ -69,12 +69,23 @@ const _isCodeGenerationStep = (step) => {
|
|
|
69
69
|
step.type === Types.VERIFY_PROPERTY ||
|
|
70
70
|
step.type === Types.SET_INPUT_FILES ||
|
|
71
71
|
step.type === Types.VERIFY_PAGE_SNAPSHOT ||
|
|
72
|
-
step.type === Types.CONDITIONAL_WAIT
|
|
72
|
+
step.type === Types.CONDITIONAL_WAIT ||
|
|
73
|
+
step.type === Types.CLOSE_PAGE
|
|
73
74
|
) {
|
|
74
75
|
return true;
|
|
75
76
|
}
|
|
76
77
|
return false;
|
|
77
78
|
};
|
|
79
|
+
|
|
80
|
+
const _isLocatorStrategyStep = (step) => {
|
|
81
|
+
switch (step.type) {
|
|
82
|
+
case Types.VERIFY_PAGE_SNAPSHOT:
|
|
83
|
+
case Types.CLOSE_PAGE:
|
|
84
|
+
return false;
|
|
85
|
+
default:
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
78
89
|
// Note: this function is used to exclude a key from an object
|
|
79
90
|
// Please move it to utils and use it as a reusable function ...
|
|
80
91
|
function excludeKey(obj, keyToRemove) {
|
|
@@ -112,7 +123,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
112
123
|
if (_isCodeGenerationStep(step) === false)
|
|
113
124
|
return { codeLines, elements: elementsChanged ? elements : null, elementIdentifier, allStrategyLocators };
|
|
114
125
|
|
|
115
|
-
if (_isCodeGenerationStep(step) && step
|
|
126
|
+
if (_isCodeGenerationStep(step) && _isLocatorStrategyStep(step)) {
|
|
116
127
|
allStrategyLocators = step.allStrategyLocators ?? splitToLocatorsGroups(step.locators);
|
|
117
128
|
let node = null;
|
|
118
129
|
|
|
@@ -728,12 +739,10 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
|
|
|
728
739
|
codePage = new CodePage(mjsFullPath);
|
|
729
740
|
codePage.generateModel();
|
|
730
741
|
}
|
|
731
|
-
//console.log("step found");
|
|
732
742
|
}
|
|
733
743
|
let elements = {};
|
|
734
744
|
if (!codePage) {
|
|
735
|
-
socketLogger.info("CodePage is null");
|
|
736
|
-
console.log("codePage is null");
|
|
745
|
+
socketLogger.info("CodePage is null", undefined, "generateCode");
|
|
737
746
|
} else {
|
|
738
747
|
elements = codePage.getVariableDeclarationAsObject("elements");
|
|
739
748
|
}
|
|
@@ -747,7 +756,7 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
|
|
|
747
756
|
if (recordingStep.type === Types.COMPLETE) {
|
|
748
757
|
return;
|
|
749
758
|
}
|
|
750
|
-
|
|
759
|
+
socketLogger.info(`Generating code for step: ${recordingStep.type}`, undefined, "generateCode");
|
|
751
760
|
|
|
752
761
|
// if (process.env.TEMP_RUN === "true") {
|
|
753
762
|
// codeLines.push(...generateReportCommand("start", recordingStep.cmdId));
|
|
@@ -759,11 +768,11 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
|
|
|
759
768
|
// codeLines.push(...generateReportCommand("end", recordingStep.cmdId));
|
|
760
769
|
// }
|
|
761
770
|
if (result.elements) {
|
|
762
|
-
|
|
771
|
+
socketLogger.info(`Updating elements with ${Object.keys(result.elements)}`, undefined, "generateCode");
|
|
763
772
|
elements = result.elements;
|
|
764
773
|
}
|
|
765
774
|
if (result.elementIdentifier) {
|
|
766
|
-
|
|
775
|
+
socketLogger.info(`Adding locator metadata for ${result.elementIdentifier}`, undefined, "generateCode");
|
|
767
776
|
locatorsMetadata[result.elementIdentifier] = result.allStrategyLocators;
|
|
768
777
|
}
|
|
769
778
|
});
|
|
@@ -800,7 +809,7 @@ const generatePageName = (url) => {
|
|
|
800
809
|
}
|
|
801
810
|
// join by _
|
|
802
811
|
return lowerCaseParts.join("_");
|
|
803
|
-
} catch
|
|
812
|
+
} catch {
|
|
804
813
|
return "default";
|
|
805
814
|
}
|
|
806
815
|
};
|
|
@@ -6,7 +6,6 @@ import os from "os";
|
|
|
6
6
|
import path from "path";
|
|
7
7
|
import { parseStepTextParameters, toCucumberExpression, unEscapeNonPrintables } from "./utils.js";
|
|
8
8
|
import stream from "stream";
|
|
9
|
-
import { testStringForRegex } from "../recorderv3/update_feature.js";
|
|
10
9
|
import { generateTestData } from "./feature_data.js";
|
|
11
10
|
import socketLogger from "../utils/socket_logger.js";
|
|
12
11
|
class DataTable {
|
|
@@ -490,8 +489,8 @@ const scenarioResolution = async (featureFilePath) => {
|
|
|
490
489
|
let result = generateTestData(featureFilePath);
|
|
491
490
|
if (result.changed) {
|
|
492
491
|
fs.writeFileSync(tmpFeatureFilePath, result.newContent);
|
|
493
|
-
|
|
494
|
-
|
|
492
|
+
socketLogger.info("Generated fake data for feature", undefined, "scenarioResolution");
|
|
493
|
+
socketLogger.info("Variables generated:", result.variables, "scenarioResolution");
|
|
495
494
|
for (let key in result.variables) {
|
|
496
495
|
console.log(`${key}: ${result.variables[key].fake}`);
|
|
497
496
|
}
|
|
@@ -503,8 +502,7 @@ const scenarioResolution = async (featureFilePath) => {
|
|
|
503
502
|
fs.copyFileSync(featureFilePath, tmpFeatureFilePath);
|
|
504
503
|
}
|
|
505
504
|
const writable = new stream.Writable({
|
|
506
|
-
write:
|
|
507
|
-
//console.log(chunk.toString());
|
|
505
|
+
write: (chunk, encoding, next) => {
|
|
508
506
|
next();
|
|
509
507
|
},
|
|
510
508
|
});
|
|
@@ -521,23 +519,12 @@ const scenarioResolution = async (featureFilePath) => {
|
|
|
521
519
|
// load the support code upfront
|
|
522
520
|
const support = await loadSupport(runConfiguration, environment);
|
|
523
521
|
// run cucumber, using the support code we loaded already
|
|
524
|
-
await runCucumber({ ...runConfiguration, support }, environment,
|
|
525
|
-
// if (event.source) {
|
|
526
|
-
// scenarioInfo.source = event.source.data;
|
|
527
|
-
// }
|
|
528
|
-
// if (event.pickle && event.pickle.name === scenarioName) {
|
|
529
|
-
// scenarioInfo.pickle = event.pickle;
|
|
530
|
-
// }
|
|
522
|
+
await runCucumber({ ...runConfiguration, support }, environment, (event) => {
|
|
531
523
|
if (event.gherkinDocument) {
|
|
532
524
|
gherkinDocument = event.gherkinDocument;
|
|
533
525
|
}
|
|
534
|
-
//console.log(event);
|
|
535
|
-
//console.log(JSON.stringify(event, null, 2));
|
|
536
|
-
// console.log("");
|
|
537
526
|
});
|
|
538
527
|
const feature = new Feature(gherkinDocument, featureFileContent);
|
|
539
|
-
//const scenario = feature.getScenario(scenarioName);
|
|
540
|
-
//return scenario;
|
|
541
528
|
return feature;
|
|
542
529
|
} finally {
|
|
543
530
|
try {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { io } from "socket.io-client";
|
|
2
2
|
import { BVTRecorder } from "./bvt_recorder.js";
|
|
3
3
|
import { compareWithScenario } from "../code_gen/duplication_analysis.js";
|
|
4
|
-
import { getAppDataDir } from "
|
|
4
|
+
import { getAppDataDir } from "../utils/app_dir.js";
|
|
5
5
|
import { readdir } from "fs/promises";
|
|
6
|
-
import socketLogger from "../utils/socket_logger.js";
|
|
6
|
+
import socketLogger, { getErrorMessage } from "../utils/socket_logger.js";
|
|
7
7
|
|
|
8
8
|
let port = process.env.EDITOR_PORT || 3003;
|
|
9
9
|
const WS_URL = process.env.WORKER_WS_SERVER_URL || "http://localhost:" + port;
|
|
@@ -34,7 +34,7 @@ class PromisifiedSocketServer {
|
|
|
34
34
|
try {
|
|
35
35
|
const handler = this.routes[event];
|
|
36
36
|
if (!handler) {
|
|
37
|
-
|
|
37
|
+
socketLogger.error(`No handler found for event: ${event}`, undefined, event);
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
40
|
const response = await handler(input);
|
|
@@ -43,15 +43,17 @@ class PromisifiedSocketServer {
|
|
|
43
43
|
}
|
|
44
44
|
this.socket.emit("response", { id, value: response, roomId, socketId });
|
|
45
45
|
} catch (error) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
socketLogger.error(
|
|
47
|
+
"Error handling request",
|
|
48
|
+
{
|
|
49
|
+
input,
|
|
50
|
+
id,
|
|
51
|
+
roomId,
|
|
52
|
+
socketId,
|
|
53
|
+
error: error instanceof Error ? `${error.message}\n${error.stack}` : error,
|
|
54
|
+
},
|
|
55
|
+
event
|
|
56
|
+
);
|
|
55
57
|
this.socket.emit("response", {
|
|
56
58
|
id,
|
|
57
59
|
error: {
|
|
@@ -75,25 +77,24 @@ const timeOutForFunction = async (promise, timeout = 5000) => {
|
|
|
75
77
|
const res = await Promise.race([promise, timeoutPromise]);
|
|
76
78
|
return res;
|
|
77
79
|
} catch (error) {
|
|
78
|
-
|
|
79
|
-
socketLogger.error(error);
|
|
80
|
+
socketLogger.error(error, undefined, "timeOutForFunction");
|
|
80
81
|
throw error;
|
|
81
82
|
}
|
|
82
83
|
};
|
|
83
84
|
|
|
85
|
+
const CLIENT_IDENTIFIER = "cucumber_client/bvt_recorder";
|
|
86
|
+
|
|
84
87
|
async function BVTRecorderInit({ envName, projectDir, roomId, TOKEN, socket = null }) {
|
|
85
|
-
console.log(
|
|
88
|
+
console.log(`Connecting to ${WS_URL}`);
|
|
86
89
|
socket = socket || io(WS_URL);
|
|
87
90
|
socketLogger.init(socket, { context: "BVTRecorder", eventName: "BVTRecorder.log" });
|
|
88
91
|
socket.on("connect", () => {
|
|
89
92
|
socketLogger.info(`${roomId} Connected to BVTRecorder server`);
|
|
90
|
-
console.log(`${roomId} Connected to BVTRecorder server`);
|
|
91
93
|
});
|
|
92
|
-
socket.on("disconnect", () => {
|
|
93
|
-
socketLogger.info(`${roomId} Disconnected from server`);
|
|
94
|
-
console.log(`${roomId} Disconnected from server`);
|
|
94
|
+
socket.on("disconnect", (reason) => {
|
|
95
|
+
socketLogger.info(`${roomId} Disconnected from server: ${reason}`);
|
|
95
96
|
});
|
|
96
|
-
socket.emit("joinRoom", { id: roomId, window:
|
|
97
|
+
socket.emit("joinRoom", { id: roomId, window: CLIENT_IDENTIFIER });
|
|
97
98
|
const recorder = new BVTRecorder({
|
|
98
99
|
envName,
|
|
99
100
|
projectDir,
|
|
@@ -104,21 +105,6 @@ async function BVTRecorderInit({ envName, projectDir, roomId, TOKEN, socket = nu
|
|
|
104
105
|
},
|
|
105
106
|
logger: socketLogger,
|
|
106
107
|
});
|
|
107
|
-
// try {
|
|
108
|
-
// await recorder.openBrowser();
|
|
109
|
-
// socketLogger.info("BVTRecorder.browserOpened");
|
|
110
|
-
// socket.emit("BVTRecorder.browserOpened", null, roomId);
|
|
111
|
-
// } catch (e) {
|
|
112
|
-
// if (e instanceof Error) {
|
|
113
|
-
// socketLogger.error("BVTRecorder.browserLaunchFailed", e);
|
|
114
|
-
// socket.emit("BVTRecorder.browserLaunchFailed", e, roomId);
|
|
115
|
-
// } else {
|
|
116
|
-
// socketLogger.error("BVTRecorder.browserLaunchFailed", JSON.stringify(e));
|
|
117
|
-
// socket.emit("BVTRecorder.browserLaunchFailed", JSON.stringify(e), roomId);
|
|
118
|
-
// }
|
|
119
|
-
// console.error("Browser launch failed", e);
|
|
120
|
-
// }
|
|
121
|
-
|
|
122
108
|
// emit connected event for every 50 ms until connection_ack message is recieved
|
|
123
109
|
let connected = false;
|
|
124
110
|
const interval = setInterval(() => {
|
|
@@ -139,12 +125,10 @@ async function BVTRecorderInit({ envName, projectDir, roomId, TOKEN, socket = nu
|
|
|
139
125
|
.openBrowser(input)
|
|
140
126
|
.then(() => {
|
|
141
127
|
socketLogger.info("BVTRecorder.browserOpened");
|
|
142
|
-
console.info("BVTRecorder.browserOpened");
|
|
143
128
|
socket.emit("BVTRecorder.browserOpened", { roomId, window: "cucumber_client/bvt_recorder" });
|
|
144
129
|
})
|
|
145
130
|
.catch((e) => {
|
|
146
|
-
socketLogger.error(
|
|
147
|
-
console.error("BVTRecorder.browserLaunchFailed", e);
|
|
131
|
+
socketLogger.error(`Error opening browser: ${getErrorMessage(e)}`, undefined, "recorderWindow.openBrowser");
|
|
148
132
|
socket.emit("BVTRecorder.browserLaunchFailed", { roomId, window: "cucumber_client/bvt_recorder" });
|
|
149
133
|
});
|
|
150
134
|
},
|
|
@@ -156,12 +140,14 @@ async function BVTRecorderInit({ envName, projectDir, roomId, TOKEN, socket = nu
|
|
|
156
140
|
.reOpenBrowser(input)
|
|
157
141
|
.then(() => {
|
|
158
142
|
socketLogger.info("BVTRecorder.browserOpened");
|
|
159
|
-
console.log("BVTRecorder.browserOpened");
|
|
160
143
|
socket.emit("BVTRecorder.browserOpened", null, roomId);
|
|
161
144
|
})
|
|
162
145
|
.catch((e) => {
|
|
163
|
-
socketLogger.
|
|
164
|
-
|
|
146
|
+
socketLogger.error(
|
|
147
|
+
`Error reopening browser: ${getErrorMessage(e)}`,
|
|
148
|
+
undefined,
|
|
149
|
+
"recorderWindow.reOpenBrowser"
|
|
150
|
+
);
|
|
165
151
|
socket.emit("BVTRecorder.browserLaunchFailed", null, roomId);
|
|
166
152
|
});
|
|
167
153
|
},
|
|
@@ -191,19 +177,15 @@ async function BVTRecorderInit({ envName, projectDir, roomId, TOKEN, socket = nu
|
|
|
191
177
|
return recorder.saveScenario(input);
|
|
192
178
|
},
|
|
193
179
|
"recorderWindow.getImplementedSteps": async (input) => {
|
|
194
|
-
// console.log("recorderWindow.getImplementedSteps", input);
|
|
195
180
|
return (await recorder.getImplementedSteps(input)).implementedSteps;
|
|
196
181
|
},
|
|
197
182
|
"recorderWindow.getImplementedScenarios": async (input) => {
|
|
198
|
-
// console.log("recorderWindow.getImplementedScenarios", input);
|
|
199
183
|
return (await recorder.getImplementedSteps(input)).scenarios;
|
|
200
184
|
},
|
|
201
185
|
"recorderWindow.getCurrentChromiumPath": async () => {
|
|
202
|
-
// console.log("recorderWindow.getCurrentChromiumPath");
|
|
203
186
|
return await recorder.getCurrentChromiumPath();
|
|
204
187
|
},
|
|
205
188
|
"recorderWindow.overwriteTestData": async (input) => {
|
|
206
|
-
// console.log("recorderWindow.overwriteTestData");
|
|
207
189
|
return await recorder.overwriteTestData(input);
|
|
208
190
|
},
|
|
209
191
|
"recorderWindow.generateStepName": async (input) => {
|
|
@@ -284,7 +266,7 @@ async function BVTRecorderInit({ envName, projectDir, roomId, TOKEN, socket = nu
|
|
|
284
266
|
return await recorder.processAriaSnapshot(snapshot);
|
|
285
267
|
}
|
|
286
268
|
},
|
|
287
|
-
"recorderWindow.revertMode": async (
|
|
269
|
+
"recorderWindow.revertMode": async () => {
|
|
288
270
|
await recorder.revertMode();
|
|
289
271
|
},
|
|
290
272
|
"recorderWindow.setMode": async (input) => {
|
|
@@ -309,46 +291,6 @@ async function BVTRecorderInit({ envName, projectDir, roomId, TOKEN, socket = nu
|
|
|
309
291
|
"recorderWindow.stopRecordingNetwork": async (input) => {
|
|
310
292
|
return recorder.stopRecordingNetwork(input);
|
|
311
293
|
},
|
|
312
|
-
"browserUI.requestState": async (input) => {
|
|
313
|
-
console.log("Received browserUI.requestState");
|
|
314
|
-
await recorder.getBrowserState();
|
|
315
|
-
},
|
|
316
|
-
"browserUI.createTab": async (input) => {
|
|
317
|
-
console.log("Received browserUI.createTab", input);
|
|
318
|
-
await recorder.createTab(input);
|
|
319
|
-
},
|
|
320
|
-
"browserUI.closeTab": async (input) => {
|
|
321
|
-
console.log("Received browserUI.closeTab", input);
|
|
322
|
-
await recorder.closeTab(input);
|
|
323
|
-
},
|
|
324
|
-
"browserUI.selectTab": async (input) => {
|
|
325
|
-
console.log("Received browserUI.selectTab", input);
|
|
326
|
-
await recorder.selectTab(input);
|
|
327
|
-
},
|
|
328
|
-
"browserUI.navigateTab": async (input) => {
|
|
329
|
-
console.log("Received browserUI.navigateTab", input);
|
|
330
|
-
await recorder.navigateTab(input);
|
|
331
|
-
},
|
|
332
|
-
"browserUI.reloadTab": async (input) => {
|
|
333
|
-
console.log("Received browserUI.reloadTab", input);
|
|
334
|
-
await recorder.reloadTab(input);
|
|
335
|
-
},
|
|
336
|
-
"browserUI.goBack": async (input) => {
|
|
337
|
-
console.log("Received browserUI.goBack", input);
|
|
338
|
-
await recorder.goBack(input);
|
|
339
|
-
},
|
|
340
|
-
"browserUI.goForward": async (input) => {
|
|
341
|
-
console.log("Received browserUI.goForward", input);
|
|
342
|
-
await recorder.goForward(input);
|
|
343
|
-
},
|
|
344
|
-
"browserUI.writeToClipboard": async (input) => {
|
|
345
|
-
console.log("Received browserUI.writeToClipboard");
|
|
346
|
-
await recorder.applyClipboardPayload(input);
|
|
347
|
-
},
|
|
348
|
-
"browserUI.readToClipboard": async (input) => {
|
|
349
|
-
console.log("Received browserUI.readToClipboard");
|
|
350
|
-
await recorder.readClipboardPayload(input);
|
|
351
|
-
},
|
|
352
294
|
"recorderWindow.cleanup": async (input) => {
|
|
353
295
|
return recorder.cleanup(input);
|
|
354
296
|
},
|
|
@@ -11,7 +11,6 @@ import { readFile, writeFile } from "fs/promises";
|
|
|
11
11
|
import {
|
|
12
12
|
loadStepDefinitions,
|
|
13
13
|
getCommandsForImplementedStep,
|
|
14
|
-
updateStepDefinitions,
|
|
15
14
|
getCodePage,
|
|
16
15
|
getCucumberStep,
|
|
17
16
|
_toRecordingStep,
|
|
@@ -22,7 +21,7 @@ import { AstBuilder, GherkinClassicTokenMatcher, Parser } from "@cucumber/gherki
|
|
|
22
21
|
import chokidar from "chokidar";
|
|
23
22
|
import { unEscapeNonPrintables } from "../cucumber/utils.js";
|
|
24
23
|
import { findAvailablePort, getRunsServiceBaseURL } from "../utils/index.js";
|
|
25
|
-
import socketLogger from "../utils/socket_logger.js";
|
|
24
|
+
import socketLogger, { getErrorMessage } from "../utils/socket_logger.js";
|
|
26
25
|
import { tmpdir } from "os";
|
|
27
26
|
import { faker } from "@faker-js/faker/locale/en_US";
|
|
28
27
|
import { chromium } from "playwright-core";
|
|
@@ -373,8 +372,7 @@ async function findNestedFrameSelector(frame, obj) {
|
|
|
373
372
|
}, frameElement);
|
|
374
373
|
return findNestedFrameSelector(parent, { children: obj, selectors });
|
|
375
374
|
} catch (e) {
|
|
376
|
-
socketLogger.error(`Error in
|
|
377
|
-
console.error(e);
|
|
375
|
+
socketLogger.error(`Error in script evaluation: ${getErrorMessage(e)}`, undefined, "findNestedFrameSelector");
|
|
378
376
|
}
|
|
379
377
|
}
|
|
380
378
|
const transformFillAction = (action, el) => {
|
|
@@ -519,7 +517,7 @@ export class BVTRecorder {
|
|
|
519
517
|
this.workspaceService = new PublishService(this.TOKEN);
|
|
520
518
|
this.pageSet = new Set();
|
|
521
519
|
this.lastKnownUrlPath = "";
|
|
522
|
-
this.world = { attach: () => {
|
|
520
|
+
this.world = { attach: () => {} };
|
|
523
521
|
this.shouldTakeScreenshot = true;
|
|
524
522
|
this.watcher = null;
|
|
525
523
|
this.networkEventsFolder = path.join(tmpdir(), "blinq_network_events");
|
|
@@ -662,7 +660,7 @@ export class BVTRecorder {
|
|
|
662
660
|
}
|
|
663
661
|
|
|
664
662
|
// this.stepRunner.setRemoteDebugPort(this.#remoteDebuggerPort);
|
|
665
|
-
this.world = { attach: () => {
|
|
663
|
+
this.world = { attach: () => {} };
|
|
666
664
|
|
|
667
665
|
const ai_config_file = path.join(this.projectDir, "ai_config.json");
|
|
668
666
|
let ai_config = {};
|
|
@@ -714,17 +712,6 @@ export class BVTRecorder {
|
|
|
714
712
|
this.web.tryAllStrategies = true;
|
|
715
713
|
this.page = bvtContext.page;
|
|
716
714
|
this.pageSet.add(this.page);
|
|
717
|
-
if (process.env.REMOTE_RECORDER === "true") {
|
|
718
|
-
this.browserEmitter = new RemoteBrowserService({
|
|
719
|
-
CDP_CONNECT_URL: `http://localhost:${this.#remoteDebuggerPort}`,
|
|
720
|
-
context: this.context,
|
|
721
|
-
});
|
|
722
|
-
this.browserEmitter.on(this.events.browserStateSync, (state) => {
|
|
723
|
-
this.page = this.browserEmitter.getSelectedPage();
|
|
724
|
-
this.sendEvent(this.events.browserStateSync, state);
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
|
|
728
715
|
this.lastKnownUrlPath = this._updateUrlPath();
|
|
729
716
|
const browser = await this.context.browser();
|
|
730
717
|
this.browser = browser;
|
|
@@ -734,8 +721,10 @@ export class BVTRecorder {
|
|
|
734
721
|
await this.context.exposeBinding(name, handler);
|
|
735
722
|
}
|
|
736
723
|
this._watchTestData();
|
|
737
|
-
this.web.onRestoreSaveState = (url) => {
|
|
738
|
-
this._initBrowser({ url });
|
|
724
|
+
this.web.onRestoreSaveState = async (url) => {
|
|
725
|
+
await this._initBrowser({ url });
|
|
726
|
+
this._addPagelisteners(this.context);
|
|
727
|
+
this._addFrameNavigateListener(this.page);
|
|
739
728
|
};
|
|
740
729
|
|
|
741
730
|
// create a second browser for locator generation
|
|
@@ -1166,7 +1155,7 @@ export class BVTRecorder {
|
|
|
1166
1155
|
}
|
|
1167
1156
|
async closeBrowser() {
|
|
1168
1157
|
delete process.env.TEMP_RUN;
|
|
1169
|
-
await this.watcher.close().then(() => {
|
|
1158
|
+
await this.watcher.close().then(() => {});
|
|
1170
1159
|
this.watcher = null;
|
|
1171
1160
|
this.previousIndex = null;
|
|
1172
1161
|
this.previousHistoryLength = null;
|
|
@@ -1327,8 +1316,6 @@ export class BVTRecorder {
|
|
|
1327
1316
|
}
|
|
1328
1317
|
}
|
|
1329
1318
|
async saveScenario({ scenario, featureName, override, isSingleStep, branch, isEditing, env, AICode }) {
|
|
1330
|
-
// await updateStepDefinitions({ scenario, featureName, projectDir: this.projectDir }); // updates mjs files
|
|
1331
|
-
// if (!isSingleStep) await updateFeatureFile({ featureName, scenario, override, projectDir: this.projectDir }); // updates gherkin files
|
|
1332
1319
|
const res = await this.workspaceService.saveScenario({
|
|
1333
1320
|
scenario,
|
|
1334
1321
|
featureName,
|
|
@@ -1513,7 +1500,7 @@ export class BVTRecorder {
|
|
|
1513
1500
|
|
|
1514
1501
|
const steps = [];
|
|
1515
1502
|
const parameters = [];
|
|
1516
|
-
const datasets = []
|
|
1503
|
+
const datasets = [];
|
|
1517
1504
|
if (scenario.examples && scenario.examples.length > 0) {
|
|
1518
1505
|
const example = scenario.examples[0];
|
|
1519
1506
|
example?.tableHeader?.cells.forEach((cell, index) => {
|
|
@@ -1521,7 +1508,7 @@ export class BVTRecorder {
|
|
|
1521
1508
|
key: cell.value,
|
|
1522
1509
|
value: unEscapeNonPrintables(example.tableBody[0].cells[index].value),
|
|
1523
1510
|
});
|
|
1524
|
-
// datasets.push({
|
|
1511
|
+
// datasets.push({
|
|
1525
1512
|
// data: example.tableBody[]
|
|
1526
1513
|
// })
|
|
1527
1514
|
});
|
|
@@ -2225,7 +2212,7 @@ export class BVTRecorder {
|
|
|
2225
2212
|
await page
|
|
2226
2213
|
.context()
|
|
2227
2214
|
.grantPermissions(["clipboard-read", "clipboard-write"])
|
|
2228
|
-
.catch(() => {
|
|
2215
|
+
.catch(() => {});
|
|
2229
2216
|
await page.evaluate(async (clipboardPayload) => {
|
|
2230
2217
|
console.log("Injecting clipboard payload", clipboardPayload);
|
|
2231
2218
|
const toArrayBuffer = (base64) => {
|
|
@@ -67,8 +67,7 @@ export class BVTStepRunner {
|
|
|
67
67
|
resolve();
|
|
68
68
|
}
|
|
69
69
|
} else {
|
|
70
|
-
|
|
71
|
-
socketLogger.error(`No paused command found for cmdId: ${cmdId}`);
|
|
70
|
+
socketLogger.error(`No paused command found for cmdId: ${cmdId}`, undefined, "BVTStepRunner.resumeExecution");
|
|
72
71
|
}
|
|
73
72
|
}
|
|
74
73
|
}
|
|
@@ -347,6 +346,7 @@ export class BVTStepRunner {
|
|
|
347
346
|
projectDir: this.projectDir,
|
|
348
347
|
stepsDefinitions,
|
|
349
348
|
parametersMap,
|
|
349
|
+
logger: socketLogger,
|
|
350
350
|
});
|
|
351
351
|
if (codePage) {
|
|
352
352
|
await codePage.save(stepDefsFilePath);
|