froth-webdriverio-framework 6.0.60 → 6.0.62
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/froth_configs/browserstack/mobile.config.js +39 -48
- package/froth_configs/browserstack/web.config.js +37 -21
- package/froth_configs/commonhook copy.js +38 -0
- package/froth_configs/commonhook.js +404 -33
- package/froth_configs/commonhook_normalsied.js +235 -0
- package/froth_configs/wdio.common.conf.js +1 -31
- package/local.log +0 -0
- package/log/key-metrics.json +490 -0
- package/log/sdk-cli-debug.log +122 -1867
- package/log/sdk-cli.log +2461 -0
- package/package.json +1 -1
- package/froth_configs/browserstack/mobilelocal.config.js +0 -39
- package/froth_configs/browserstack/weblocal.config.js +0 -25
- package/froth_configs/commonconfig.js +0 -410
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
|
|
2
|
+
const setAllDetails = require('./setallDatailinBuffer');
|
|
3
|
+
const exeDetails = require('../froth_api_calls/getexecutionDetails');
|
|
4
|
+
const { getBSSessionDetails } = require('../froth_api_calls/browsersatckSessionInfo');
|
|
5
|
+
let globalErrorHandled = false;
|
|
6
|
+
let suiteStartTime;
|
|
7
|
+
let totalTestDuration = 0;
|
|
8
|
+
const url = require('url');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const resultdetails = {
|
|
13
|
+
comments: [],
|
|
14
|
+
excution_status: null,
|
|
15
|
+
excution_time: null
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/* ----------------- GLOBAL ERROR HANDLERS ----------------- */
|
|
19
|
+
let globalErrorRegistered = false;
|
|
20
|
+
function registerGlobalErrorHandlers() {
|
|
21
|
+
if (globalErrorRegistered) return;
|
|
22
|
+
globalErrorRegistered = true;
|
|
23
|
+
|
|
24
|
+
process.on('uncaughtException', async (err) => {
|
|
25
|
+
console.error('🔥 Uncaught Exception:', err);
|
|
26
|
+
resultdetails.excution_status = 'FAILED';
|
|
27
|
+
resultdetails.comments.push(`Uncaught Exception: ${err.message}`);
|
|
28
|
+
await safeUpdateExecution();
|
|
29
|
+
process.exit(1);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
process.on('unhandledRejection', async (reason) => {
|
|
33
|
+
console.error('🔥 Unhandled Rejection:', reason);
|
|
34
|
+
resultdetails.excution_status = 'FAILED';
|
|
35
|
+
resultdetails.comments.push(`Unhandled Rejection: ${reason?.message || reason}`);
|
|
36
|
+
await safeUpdateExecution();
|
|
37
|
+
process.exit(1);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function safeUpdateExecution() {
|
|
42
|
+
try {
|
|
43
|
+
await exeDetails.updateExecuitonDetails(
|
|
44
|
+
BUFFER.getItem('ORGANISATION_DOMAIN_URL'),
|
|
45
|
+
BUFFER.getItem('FROTH_LOGIN_TOKEN'),
|
|
46
|
+
BUFFER.getItem('FROTH_EXECUTION_ID'),
|
|
47
|
+
resultdetails
|
|
48
|
+
);
|
|
49
|
+
} catch (e) {
|
|
50
|
+
console.error('❌ Failed to update execution details:', e.message);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* ----------------- HELPER FUNCTIONS ----------------- */
|
|
55
|
+
function msToTime(ms) {
|
|
56
|
+
const sec = Math.floor(ms / 1000);
|
|
57
|
+
return new Date(sec * 1000).toISOString().substr(11, 8);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function failExecution(reason) {
|
|
61
|
+
resultdetails.excution_status = 'FAILED';
|
|
62
|
+
resultdetails.comments.push(reason);
|
|
63
|
+
await safeUpdateExecution();
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
/* ------------------ COMMON CONFIG ------------------ */
|
|
67
|
+
|
|
68
|
+
const commonHooks = {
|
|
69
|
+
|
|
70
|
+
/* ========== ON PREPARE ========== */
|
|
71
|
+
onPrepare: async () => {
|
|
72
|
+
registerGlobalErrorHandlers();
|
|
73
|
+
|
|
74
|
+
console.log('==== ON PREPARE HOOK ====');
|
|
75
|
+
await setAllDetails.setEnvVariables();
|
|
76
|
+
await setAllDetails.setExecutionDetails();
|
|
77
|
+
await setAllDetails.setSuiteDetails();
|
|
78
|
+
await setAllDetails.setTestDataDetails();
|
|
79
|
+
|
|
80
|
+
console.log('✅ All Env Varibale set');
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/* ========== BEFORE SESSION ========== */
|
|
84
|
+
|
|
85
|
+
beforeSession: async function (config, capabilities, specs) {
|
|
86
|
+
console.log('==== BEFORE SESSION ====');
|
|
87
|
+
try {
|
|
88
|
+
/** 1️⃣ Validate test syntax */
|
|
89
|
+
let syntaxFailed = false;
|
|
90
|
+
|
|
91
|
+
for (const fileUrl of specs) {
|
|
92
|
+
const filePath = url.fileURLToPath(fileUrl);
|
|
93
|
+
try {
|
|
94
|
+
new Function(fs.readFileSync(filePath, 'utf8'));
|
|
95
|
+
} catch (err) {
|
|
96
|
+
const msg = `❌ Syntax error in ${path.basename(filePath)}: ${err.message}`;
|
|
97
|
+
console.error(msg);
|
|
98
|
+
resultdetails.comments.push(msg);
|
|
99
|
+
syntaxFailed = true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (syntaxFailed) {
|
|
104
|
+
await failExecution('Syntax validation failed');
|
|
105
|
+
}
|
|
106
|
+
/** 2️⃣ BrowserStack capability normalization */
|
|
107
|
+
|
|
108
|
+
if (process.env.PLATFORM === 'browserstack' || process.env.PLATFORM === 'browserstacklocal') {
|
|
109
|
+
const bsOpts = capabilities['bstack:options'] || {};
|
|
110
|
+
if (process.env.BS_SESSION_TYPE === 'app-automate') {
|
|
111
|
+
const appPath = process.env.BROWSERSTACK_APP_PATH;
|
|
112
|
+
if (!appPath) {
|
|
113
|
+
await failExecution('BROWSERSTACK_APP_PATH is missing');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
bsOpts.app = appPath;
|
|
117
|
+
capabilities['appium:app'] = appPath;
|
|
118
|
+
console.log('✅ App & media set in before session');
|
|
119
|
+
|
|
120
|
+
}
|
|
121
|
+
/** Media upload */
|
|
122
|
+
if (process.env.MEDIA_FILES) {
|
|
123
|
+
try {
|
|
124
|
+
bsOpts['browserstack.uploadMedia'] = JSON.parse(process.env.MEDIA_FILES);
|
|
125
|
+
} catch {
|
|
126
|
+
console.warn('⚠️ MEDIA_FILES is not valid JSON');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
capabilities['bstack:options'] = bsOpts;
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
console.log('final cinfig dteials :' + JSON.stringify(capabilities))
|
|
133
|
+
|
|
134
|
+
console.log("config details " + JSON.stringify(config))
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error('🚨 Error in beforeSession:', error);
|
|
139
|
+
console.error('🚨 Error in beforeSession:', error.message);
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
/* ========== BEFORE SUITE ========== */
|
|
143
|
+
beforeSuite: async (suite) => {
|
|
144
|
+
console.log(`==== BEFORE SUITE: ${suite.title} ====`);
|
|
145
|
+
suiteStartTime = Date.now();
|
|
146
|
+
|
|
147
|
+
if (process.env.PLATFORM === 'browserstack' || process.env.PLATFORM === 'browserstacklocal') {
|
|
148
|
+
await getBSSessionDetails(
|
|
149
|
+
process.env.BS_SESSION_TYPE,
|
|
150
|
+
process.env.BROWSERSTACK_USERNAME,
|
|
151
|
+
process.env.BROWSERSTACK_ACCESS_KEY
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
await exeDetails.update_CICDRUNID_ReportUrl(
|
|
156
|
+
BUFFER.getItem('ORGANISATION_DOMAIN_URL'),
|
|
157
|
+
BUFFER.getItem('FROTH_LOGIN_TOKEN'),
|
|
158
|
+
BUFFER.getItem('FROTH_EXECUTION_ID')
|
|
159
|
+
);
|
|
160
|
+
},
|
|
161
|
+
/* ========== BEFORE TEST ========== */
|
|
162
|
+
beforeTest: async (test) => {
|
|
163
|
+
console.log(`▶️ START TEST: ${test.title}`);
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
/* ========== AFTER TEST ========== */
|
|
167
|
+
afterTest: async (test, _, { error, duration, passed }) => {
|
|
168
|
+
totalTestDuration += duration;
|
|
169
|
+
|
|
170
|
+
const fileName = path.basename(test.file);
|
|
171
|
+
const status = passed ? 'PASSED' : 'FAILED';
|
|
172
|
+
|
|
173
|
+
if (!passed) {
|
|
174
|
+
resultdetails.comments.push(`${test.title} - ${error?.message || 'Failed'}`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const suiteDetails = JSON.parse(BUFFER.getItem('FROTHE_SUITE_DETAILS'));
|
|
178
|
+
const script = suiteDetails.find(s => s.scriptName === fileName.replace('.js', ''));
|
|
179
|
+
|
|
180
|
+
await exeDetails.updateScriptExecutionStatus(
|
|
181
|
+
BUFFER.getItem('ORGANISATION_DOMAIN_URL'),
|
|
182
|
+
BUFFER.getItem('FROTH_LOGIN_TOKEN'),
|
|
183
|
+
script.scriptId,
|
|
184
|
+
script.platform.toLowerCase(),
|
|
185
|
+
status
|
|
186
|
+
);
|
|
187
|
+
},
|
|
188
|
+
/* ==== AFTER SESSION ==== */
|
|
189
|
+
afterSession: async (config, capabilities, specs, exitCode) => {
|
|
190
|
+
console.log('==== AFTER SESSION ====');
|
|
191
|
+
|
|
192
|
+
const totalTime = Date.now() - suiteStartTime;
|
|
193
|
+
resultdetails.excution_status = exitCode === 0 ? 'PASSED' : 'FAILED';
|
|
194
|
+
resultdetails.excution_time = msToTime(Math.max(totalTime, totalTestDuration));
|
|
195
|
+
|
|
196
|
+
// Capture WebDriver session failures
|
|
197
|
+
if (exitCode !== 0) {
|
|
198
|
+
resultdetails.comments.push(`❌ WebDriver session failed or timed out (exit code ${exitCode})`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
await safeUpdateExecution();
|
|
202
|
+
BUFFER.clear();
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
/* ========== ON ERROR ========== */
|
|
206
|
+
|
|
207
|
+
onError: async function (error) {
|
|
208
|
+
console.error('==== ON ERROR HOOK ====');
|
|
209
|
+
console.error('Error occurred:', error.message);
|
|
210
|
+
|
|
211
|
+
// Normalize all framework-level failures
|
|
212
|
+
resultdetails.excution_status = 'FAILED';
|
|
213
|
+
resultdetails.comments.push(`WDIO Error: ${error.message}`);
|
|
214
|
+
|
|
215
|
+
// Special handling for BrowserStack timeout
|
|
216
|
+
if (error.message?.includes('Automate testing time expired')) {
|
|
217
|
+
resultdetails.comments.push(
|
|
218
|
+
'BrowserStack session timed out (Automate testing time expired)'
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await safeUpdateExecution();
|
|
223
|
+
},
|
|
224
|
+
/* ========== ON COMPLETE ========== */
|
|
225
|
+
onComplete: async (exitCode, _, __, results) => {
|
|
226
|
+
console.log('==== ON COMPLETE ====');
|
|
227
|
+
console.log(`Total: ${results.total}, Passed: ${results.passed}, Failed: ${results.failed}`);
|
|
228
|
+
return exitCode;
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
module.exports = commonHooks;
|
|
@@ -48,16 +48,11 @@ console.log('====> BS SESSION TYPE :', process.env.BS_SESSION_TYPE);
|
|
|
48
48
|
// --------------------
|
|
49
49
|
// Load env-specific config
|
|
50
50
|
// --------------------
|
|
51
|
-
if (PLATFORM === 'browserstack') {
|
|
51
|
+
if (PLATFORM === 'browserstack' || PLATFORM === 'browserstacklocal') {
|
|
52
52
|
envConfig =
|
|
53
53
|
OS === 'web'
|
|
54
54
|
? require('./browserstack/web.config')
|
|
55
55
|
: require('./browserstack/mobile.config');
|
|
56
|
-
} else if (PLATFORM === 'browserstacklocal') {
|
|
57
|
-
envConfig =
|
|
58
|
-
OS === 'web'
|
|
59
|
-
? require('./browserstack/weblocal.config')
|
|
60
|
-
: require('./browserstack/mobilelocal.config');
|
|
61
56
|
} else {
|
|
62
57
|
envConfig =
|
|
63
58
|
OS === 'web'
|
|
@@ -68,28 +63,3 @@ if (PLATFORM === 'browserstack') {
|
|
|
68
63
|
|
|
69
64
|
exports.config = deepmerge(baseConfig, envConfig(bsCaps));
|
|
70
65
|
|
|
71
|
-
// Merge base + env config
|
|
72
|
-
//const finalConfig = deepmerge(baseConfig, envConfig(bsCaps));
|
|
73
|
-
|
|
74
|
-
// --------------------
|
|
75
|
-
// Before session hook to dynamically update app
|
|
76
|
-
// --------------------
|
|
77
|
-
// finalConfig.beforeSession = async function (config, capabilities, specs) {
|
|
78
|
-
// if (OS === 'mobile') {
|
|
79
|
-
// console.log('====> Updating app before session');
|
|
80
|
-
// await setAllDetails.setEnvVariables();
|
|
81
|
-
// getExeDetails = await setAllDetails.setExecutionDetails();
|
|
82
|
-
// await setAllDetails.setSuiteDetails();
|
|
83
|
-
// await setAllDetails.setTestDataDetails();
|
|
84
|
-
|
|
85
|
-
// // const appPath = process.env.BROWSERSTACK_APP_PATH || bsCaps.app;
|
|
86
|
-
// // // Find the browserstack service object
|
|
87
|
-
// // const bsService = config.services.find(s => Array.isArray(s) && s[0] === 'browserstack');
|
|
88
|
-
// // if (bsService && bsService[1]) {
|
|
89
|
-
// // bsService[1].app = process.env.BROWSERSTACK_APP_PATH || bsCaps.app;
|
|
90
|
-
// // console.log('====> App path set to:', bsService[1].app);
|
|
91
|
-
// // }
|
|
92
|
-
// };
|
|
93
|
-
// }
|
|
94
|
-
|
|
95
|
-
//exports.config = finalConfig;
|
package/local.log
CHANGED
|
Binary file
|