froth-webdriverio-framework 7.0.67 → 7.0.69
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/commonhook.js +177 -65
- package/package.json +1 -1
|
@@ -105,6 +105,10 @@ const commonHooks = {
|
|
|
105
105
|
await setAllDetails.setSuiteDetails();
|
|
106
106
|
await setAllDetails.setTestDataDetails();
|
|
107
107
|
|
|
108
|
+
await setupBrowserStackCapabilities(config);
|
|
109
|
+
|
|
110
|
+
console.log('🚀 Final BrowserStack capabilities (onPrepare):');
|
|
111
|
+
console.log(JSON.stringify(config.capabilities, null, 2));
|
|
108
112
|
console.log('✅ All Environment Variables:');
|
|
109
113
|
// for (const [key, value] of Object.entries(process.env)) {
|
|
110
114
|
// console.log(`${key} = ${value}`);
|
|
@@ -134,80 +138,96 @@ const commonHooks = {
|
|
|
134
138
|
|
|
135
139
|
|
|
136
140
|
/* ========== BEFORE SESSION ========== */
|
|
137
|
-
|
|
138
141
|
beforeSession: async function (config, capabilities, specs) {
|
|
139
|
-
console.log('==== BEFORE SESSION ====');
|
|
140
|
-
try {
|
|
141
|
-
/** 1️⃣ Validate test syntax */
|
|
142
|
-
let syntaxFailed = false;
|
|
143
|
-
|
|
144
|
-
for (const fileUrl of specs) {
|
|
145
|
-
const filePath = url.fileURLToPath(fileUrl);
|
|
146
|
-
try {
|
|
147
|
-
new Function(fs.readFileSync(filePath, 'utf8'));
|
|
148
|
-
} catch (err) {
|
|
149
|
-
const msg = `❌ Syntax error in ${path.basename(filePath)}: ${err.message}`;
|
|
150
|
-
console.error(msg);
|
|
151
|
-
resultdetails.comments.push(msg);
|
|
152
|
-
syntaxFailed = true;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (syntaxFailed) {
|
|
157
|
-
await failExecution('Syntax validation failed');
|
|
158
|
-
}
|
|
159
|
-
/** 2️⃣ BrowserStack capability normalization */
|
|
160
|
-
|
|
161
|
-
if (process.env.PLATFORM === 'browserstack' || process.env.PLATFORM === 'browserstacklocal') {
|
|
162
|
-
/** 🔍 Print raw capabilities first */
|
|
163
|
-
console.log('🟡 Raw Capabilities (Before):');
|
|
164
|
-
console.log(JSON.stringify(capabilities, null, 2));
|
|
165
|
-
const bsOpts = capabilities['bstack:options'] || {};
|
|
166
|
-
/** 🔍 Print existing BS options */
|
|
167
|
-
console.log('🟢 Existing bstack:options (Before Modification):');
|
|
168
|
-
console.log(JSON.stringify(bsOpts, null, 2));
|
|
169
|
-
|
|
170
|
-
if (process.env.BS_SESSION_TYPE === 'app-automate') {
|
|
171
|
-
const appPath = process.env.BROWSERSTACK_APP_PATH;
|
|
172
|
-
if (!appPath) {
|
|
173
|
-
await failExecution('BROWSERSTACK_APP_PATH is missing');
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
bsOpts.app = appPath;
|
|
177
|
-
capabilities['appium:app'] = appPath;
|
|
178
|
-
console.log('✅ App & media set in before session');
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
/** Media upload */
|
|
182
|
-
/** 📦 Media upload (from DB → ENV → capabilities) */
|
|
183
|
-
if (process.env.MEDIA_FILES) {
|
|
184
|
-
try {
|
|
185
|
-
const mediaList = JSON.parse(process.env.MEDIA_FILES);
|
|
186
|
-
console.log("media files are", mediaList)
|
|
187
|
-
if (Array.isArray(mediaList) && mediaList.length > 0) {
|
|
188
|
-
bsOpts.uploadMedia = mediaList;
|
|
189
|
-
console.log('✅ uploadMedia injected:', mediaList);
|
|
190
|
-
}
|
|
191
|
-
} catch (err) {
|
|
192
|
-
console.warn('⚠️ MEDIA_FILES is not valid JSON', err);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
capabilities['bstack:options'] = bsOpts;
|
|
196
|
-
/** 🔍 Print final BS options */
|
|
197
|
-
console.log('🔵 Final bstack:options (After Modification):');
|
|
198
|
-
console.log(JSON.stringify(capabilities['bstack:options'], null, 2));
|
|
142
|
+
console.log('==== BEFORE SESSION STARTED ====');
|
|
199
143
|
|
|
200
|
-
|
|
201
|
-
|
|
144
|
+
try {
|
|
145
|
+
/** 1️⃣ Validate syntax */
|
|
146
|
+
await validateTestSyntax(specs);
|
|
202
147
|
|
|
203
|
-
|
|
148
|
+
/** 2️⃣ Setup BrowserStack */
|
|
149
|
+
// await setupBrowserStackCapabilities(capabilities);
|
|
204
150
|
|
|
151
|
+
console.log('✅ beforeSession completed successfully');
|
|
205
152
|
|
|
206
153
|
} catch (error) {
|
|
207
|
-
console.error('🚨 Error in beforeSession:', error);
|
|
208
154
|
console.error('🚨 Error in beforeSession:', error.message);
|
|
155
|
+
throw error;
|
|
209
156
|
}
|
|
210
157
|
},
|
|
158
|
+
// beforeSession: async function (config, capabilities, specs) {
|
|
159
|
+
// console.log('==== BEFORE SESSION ====');
|
|
160
|
+
// try {
|
|
161
|
+
// /** 1️⃣ Validate test syntax */
|
|
162
|
+
// let syntaxFailed = false;
|
|
163
|
+
|
|
164
|
+
// for (const fileUrl of specs) {
|
|
165
|
+
// const filePath = url.fileURLToPath(fileUrl);
|
|
166
|
+
// try {
|
|
167
|
+
// new Function(fs.readFileSync(filePath, 'utf8'));
|
|
168
|
+
// } catch (err) {
|
|
169
|
+
// const msg = `❌ Syntax error in ${path.basename(filePath)}: ${err.message}`;
|
|
170
|
+
// console.error(msg);
|
|
171
|
+
// resultdetails.comments.push(msg);
|
|
172
|
+
// syntaxFailed = true;
|
|
173
|
+
// }
|
|
174
|
+
// }
|
|
175
|
+
|
|
176
|
+
// if (syntaxFailed) {
|
|
177
|
+
// await failExecution('Syntax validation failed');
|
|
178
|
+
// }
|
|
179
|
+
// /** 2️⃣ BrowserStack capability normalization */
|
|
180
|
+
|
|
181
|
+
// if (process.env.PLATFORM === 'browserstack' || process.env.PLATFORM === 'browserstacklocal') {
|
|
182
|
+
// /** 🔍 Print raw capabilities first */
|
|
183
|
+
// console.log('🟡 Raw Capabilities (Before):');
|
|
184
|
+
// console.log(JSON.stringify(capabilities, null, 2));
|
|
185
|
+
// const bsOpts = capabilities['bstack:options'] || {};
|
|
186
|
+
// /** 🔍 Print existing BS options */
|
|
187
|
+
// console.log('🟢 Existing bstack:options (Before Modification):');
|
|
188
|
+
// console.log(JSON.stringify(bsOpts, null, 2));
|
|
189
|
+
|
|
190
|
+
// if (process.env.BS_SESSION_TYPE === 'app-automate') {
|
|
191
|
+
// const appPath = process.env.BROWSERSTACK_APP_PATH;
|
|
192
|
+
// if (!appPath) {
|
|
193
|
+
// await failExecution('BROWSERSTACK_APP_PATH is missing');
|
|
194
|
+
// }
|
|
195
|
+
|
|
196
|
+
// bsOpts.app = appPath;
|
|
197
|
+
// capabilities['appium:app'] = appPath;
|
|
198
|
+
// console.log('✅ App & media set in before session');
|
|
199
|
+
|
|
200
|
+
// }
|
|
201
|
+
// /** Media upload */
|
|
202
|
+
// /** 📦 Media upload (from DB → ENV → capabilities) */
|
|
203
|
+
// if (process.env.MEDIA_FILES) {
|
|
204
|
+
// try {
|
|
205
|
+
// const mediaList = JSON.parse(process.env.MEDIA_FILES);
|
|
206
|
+
// console.log("media files are", mediaList)
|
|
207
|
+
// if (Array.isArray(mediaList) && mediaList.length > 0) {
|
|
208
|
+
// bsOpts.uploadMedia = mediaList;
|
|
209
|
+
// console.log('✅ uploadMedia injected:', mediaList);
|
|
210
|
+
// }
|
|
211
|
+
// } catch (err) {
|
|
212
|
+
// console.warn('⚠️ MEDIA_FILES is not valid JSON', err);
|
|
213
|
+
// }
|
|
214
|
+
// }
|
|
215
|
+
// capabilities['bstack:options'] = bsOpts;
|
|
216
|
+
// /** 🔍 Print final BS options */
|
|
217
|
+
// console.log('🔵 Final bstack:options (After Modification):');
|
|
218
|
+
// console.log(JSON.stringify(capabilities['bstack:options'], null, 2));
|
|
219
|
+
|
|
220
|
+
// }
|
|
221
|
+
// console.log('🔎 Final capabilities:', JSON.stringify(capabilities, null, 2));
|
|
222
|
+
|
|
223
|
+
// // console.log("config details " + JSON.stringify(config))
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
// } catch (error) {
|
|
227
|
+
// console.error('🚨 Error in beforeSession:', error);
|
|
228
|
+
// console.error('🚨 Error in beforeSession:', error.message);
|
|
229
|
+
// }
|
|
230
|
+
// },
|
|
211
231
|
/* ========== BEFORE SUITE ========== */
|
|
212
232
|
beforeSuite: async (suite) => {
|
|
213
233
|
console.log(`==== BEFORE SUITE: ${suite.title} ====`);
|
|
@@ -374,5 +394,97 @@ async function normalizeWdioError(error) {
|
|
|
374
394
|
return `Automation framework error: ${msg}`;
|
|
375
395
|
}
|
|
376
396
|
|
|
397
|
+
async function setupBrowserStackCapabilities(capabilities) {
|
|
398
|
+
if (
|
|
399
|
+
process.env.PLATFORM !== 'browserstack' &&
|
|
400
|
+
process.env.PLATFORM !== 'browserstacklocal'
|
|
401
|
+
) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const bsOpts = capabilities['bstack:options'] || {};
|
|
406
|
+
|
|
407
|
+
/** 🔹 Build metadata */
|
|
408
|
+
bsOpts.buildIdentifier =
|
|
409
|
+
process.env.BROWSERSTACK_BUILD_NAME || 'local-build';
|
|
410
|
+
|
|
411
|
+
bsOpts.buildName =
|
|
412
|
+
process.env.BROWSERSTACK_BUILD_DISPLAY_NAME ||
|
|
413
|
+
bsOpts.buildName
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
bsOpts.projectName = bsOpts.projectName || 'BrowserStack Samples';
|
|
417
|
+
|
|
418
|
+
bsOpts.sessionName =
|
|
419
|
+
process.env.BROWSERSTACK_SESSION_NAME ||
|
|
420
|
+
'BStack WDIO Appium Session';
|
|
421
|
+
|
|
422
|
+
/** 🔹 Device consistency */
|
|
423
|
+
bsOpts.deviceName = bsOpts.deviceName || capabilities.deviceName;
|
|
424
|
+
bsOpts.osVersion = bsOpts.osVersion || capabilities.osVersion;
|
|
425
|
+
|
|
426
|
+
/** 🔹 Logs */
|
|
427
|
+
bsOpts.debug = bsOpts.debug ?? true;
|
|
428
|
+
bsOpts.networkLogs = bsOpts.networkLogs ?? false;
|
|
429
|
+
|
|
430
|
+
/** 🔹 Local testing */
|
|
431
|
+
if (process.env.PLATFORM === 'browserstacklocal') {
|
|
432
|
+
bsOpts.local = true;
|
|
433
|
+
bsOpts.localIdentifier =
|
|
434
|
+
process.env.BROWSERSTACK_LOCAL_IDENTIFIER ||
|
|
435
|
+
`wdio-${process.pid}`;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/** 🔹 App Automate */
|
|
439
|
+
if (process.env.BS_SESSION_TYPE === 'app-automate') {
|
|
440
|
+
const appPath = process.env.BROWSERSTACK_APP_PATH;
|
|
441
|
+
|
|
442
|
+
if (!appPath) {
|
|
443
|
+
throw new Error('❌ BROWSERSTACK_APP_PATH is missing');
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
bsOpts.app = appPath;
|
|
447
|
+
capabilities['appium:app'] = appPath;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/** 🔹 Media upload */
|
|
451
|
+
if (process.env.MEDIA_FILES) {
|
|
452
|
+
try {
|
|
453
|
+
const mediaList = JSON.parse(process.env.MEDIA_FILES);
|
|
454
|
+
if (Array.isArray(mediaList) && mediaList.length > 0) {
|
|
455
|
+
bsOpts.uploadMedia = mediaList;
|
|
456
|
+
}
|
|
457
|
+
} catch (err) {
|
|
458
|
+
console.warn('⚠️ MEDIA_FILES is not valid JSON', err);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/** 🔹 Re-assign */
|
|
463
|
+
capabilities['bstack:options'] = bsOpts;
|
|
464
|
+
|
|
465
|
+
/** 🔹 Final BS log */
|
|
466
|
+
console.log('🚀 BrowserStack final options:');
|
|
467
|
+
console.log(JSON.stringify(bsOpts, null, 2));
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
async function validateTestSyntax(specs) {
|
|
471
|
+
let syntaxFailed = false;
|
|
472
|
+
|
|
473
|
+
for (const fileUrl of specs) {
|
|
474
|
+
const filePath = url.fileURLToPath(fileUrl);
|
|
475
|
+
try {
|
|
476
|
+
new Function(fs.readFileSync(filePath, 'utf8'));
|
|
477
|
+
} catch (err) {
|
|
478
|
+
console.error(
|
|
479
|
+
`❌ Syntax error in ${path.basename(filePath)}: ${err.message}`
|
|
480
|
+
);
|
|
481
|
+
syntaxFailed = true;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (syntaxFailed) {
|
|
486
|
+
throw new Error('Syntax validation failed');
|
|
487
|
+
}
|
|
488
|
+
}
|
|
377
489
|
|
|
378
490
|
module.exports = commonHooks;
|