froth-webdriverio-framework 6.0.7 → 6.0.9

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.
@@ -8,7 +8,6 @@ const exeDetails = require("../froth_api_calls/getexecutionDetails")
8
8
  const getBSSessionDetails = require("../froth_api_calls/browsersatckSessionInfo").getBSSessionDetails;
9
9
  const { fail } = require("assert");
10
10
  const { error } = require('console');
11
- const browserstack = require("browserstack-local");
12
11
  //const isBrowserStackEnabled = process.env.BROWSERSTACK;
13
12
  let starttime;
14
13
  let endtime;
@@ -19,7 +18,6 @@ const resultdetails = {
19
18
  excution_status: null, // Pass/Fail
20
19
  excution_time: null, // Execution time in milliseconds
21
20
  };
22
- let bsLocal;
23
21
  // Description: This file contains the common configuration for the webdriverio framework.
24
22
  const commonconfig = {
25
23
 
@@ -84,42 +82,22 @@ const commonconfig = {
84
82
  console.log("====> BROWSERSTACK_LOCAL : " + process.env.BROWSERSTACK_LOCAL);
85
83
  console.log("Local enabled? →", capabilities['bstack:options']?.local);
86
84
 
87
- // const isLocalEnabled = process.env.BROWSERSTACK_LOCAL === "true";
88
-
89
- // if (isLocalEnabled) {
90
- // bsLocal = new browserstack.Local();
91
- // const localArgs = {
92
- // key: process.env.BROWSERSTACK_ACCESS_KEY,
93
- // forceLocal: true,
94
- // localIdentifier: capabilities.localIdentifier || 'wdioLocal'
95
- // };
96
-
97
- // await new Promise((resolve, reject) => {
98
- // bsLocal.start(localArgs, function (error) {
99
- // if (error) return reject(error);
100
- // console.log("====> BrowserStack Local started successfully.");
101
- // resolve();
102
- // });
103
- // });
104
-
105
- // // Add Local settings into capabilities dynamically
106
- // capabilities['browserstack.local'] = true;
107
- // capabilities['browserstack.localIdentifier'] = localArgs.localIdentifier || 'ExecuteLocal';
108
- // }
109
- // else {
110
- // console.log("====> BROWSERSTACK_LOCAL not set. Skipping BrowserStack Local startup." + process.env.BROWSERSTACK_LOCAL);
111
- // // Make sure no stale values from config remain
112
- // delete capabilities['browserstack.local'];
113
- // delete capabilities['browserstack.localIdentifier'];
114
- // }
85
+ const isLocalEnabled = process.env.BROWSERSTACK_LOCAL === "true";
86
+
87
+ if (isLocalEnabled) {
88
+ console.log("====> Starting BrowserStack Local...");
89
+ if (!capabilities['bstack:options']) capabilities['bstack:options'] = {};
90
+ capabilities['bstack:options'].browserstackLocal = true;
91
+ console.log("✔ BrowserStack Local enabled dynamically");
92
+ }
115
93
 
116
94
  // capabilities.accessKey = Buffer.from(capabilities.accessKey, 'base64').toString('utf-8');
117
95
  if (capabilities.platformName === 'android' || capabilities.platformName === 'ios') {
118
96
  capabilities['appium:app'] = process.env.BROWSERSTACK_APP_PATH;
119
-
120
97
  // capabilities.app = process.env.BROWSERSTACK_APP_PATH;
121
98
  const appValue = capabilities['appium:app'];
122
- console.log("App Value:", appValue);
99
+ console.log("App Value=====>", appValue);
100
+
123
101
  if (appValue === undefined || appValue === null || appValue === '') {
124
102
  console.error("🚨 Error: BROWSERSTACK_APP_PATH is not defined or empty.");
125
103
  resultdetails.excution_status = 'FAILED';
@@ -20,11 +20,13 @@ const resultdetails = {
20
20
  // Load YAML file
21
21
  //const capabilities = yaml.load(fs.readFileSync(path.join(path.resolve(process.cwd(), configFile)), 'utf8'));
22
22
 
23
- let capabilities;
23
+ let rawCaps;
24
24
 
25
25
  try {
26
- capabilities = yaml.load(fs.readFileSync(path.join(path.resolve(process.cwd(), configFile)), 'utf8'));
26
+ rawCaps = yaml.load(fs.readFileSync(path.join(path.resolve(process.cwd(), configFile)), 'utf8'));
27
27
  // Merge chrome-specific options if applicable
28
+ console.log("==== RAW YAML ====", rawCaps);
29
+
28
30
 
29
31
  } catch (e) {
30
32
  const errorMsg = `The capability file does not exist in the currently configured repository at path: ${path.resolve(process.cwd(), configFile)}: ${e.message},Please update the Capability by editing the file`;
@@ -49,20 +51,16 @@ try {
49
51
  }
50
52
  process.exit(1);
51
53
  }
52
- console.log('====>capabilities:', capabilities);
53
54
 
55
+ console.log('====>capabilities:', rawCaps);
54
56
  const SUITE_FILE = path.resolve(process.cwd(), process.env.SUITE);
55
57
  console.log('====>SUITE_FILE:', SUITE_FILE);
56
58
 
57
59
  if (!SUITE_FILE || !fs.existsSync(SUITE_FILE)) {
58
60
  let errorMsg = `The suite file does not exist in the currently configured repository at path: ${SUITE_FILE}. Please update the SUITE by editing the file`;
59
-
60
61
  console.error(errorMsg);
61
62
  resultdetails.comments.push(errorMsg);
62
63
  resultdetails.excution_status = 'FAIL';
63
-
64
- // Fire API call in background (non-blocking)
65
-
66
64
  try {
67
65
  exeDetails.updateExecuitonDetails(
68
66
  process.env.ORGANISATION_DOMAIN_URL,
@@ -72,7 +70,6 @@ if (!SUITE_FILE || !fs.existsSync(SUITE_FILE)) {
72
70
  );
73
71
  setTimeout(() => {
74
72
  console.log("30 seconds passed.");
75
- // You can call your API or exit the process here
76
73
  }, 30000);
77
74
  console.log('Execution details updated successfully.');
78
75
  } catch (err) {
@@ -81,86 +78,88 @@ if (!SUITE_FILE || !fs.existsSync(SUITE_FILE)) {
81
78
  process.exit(1);
82
79
  }
83
80
 
84
- function setupPrerequisites() {
85
- console.log("inside this fuction first ");
81
+ function setupPrerequisites(rawCaps) {
82
+ console.log("==== Running setupPrerequisites() ====");
86
83
  if (PLATFORM === 'browserstack') {
87
- process.env.BROWSERSTACK_USERNAME = capabilities.userName;
88
- capabilities.accessKey = Buffer.from(capabilities.accessKey, 'base64').toString('utf-8');
89
- process.env.BROWSERSTACK_ACCESS_KEY = capabilities.accessKey
90
- console.log('capabilities.platformName:', capabilities.platformName ?? 'web');
91
-
92
- // Determine session type automatically
93
- const isMobile =
94
- capabilities.platformName &&
95
- (capabilities.platformName.toLowerCase() === "android" ||
96
- capabilities.platformName.toLowerCase() === "ios");
97
-
98
- if (isMobile) {
99
- process.env.BS_SESSION_TYPE = "app-automate";
100
- } else {
101
- process.env.BS_SESSION_TYPE = "automate";
102
- }
103
- // process.env.BS_SESSION_TYPE = capabilities.platformName === 'android' || capabilities.platformName === 'ios' ? 'app-automate' : 'automate';
104
- capabilities.buildName = process.env.FROTH_TESTOPS_BUILD_NAME;
84
+ process.env.BROWSERSTACK_USERNAME = rawCaps.userName;
85
+ rawCaps.accessKey = Buffer.from(rawCaps.accessKey, 'base64').toString('utf-8');
86
+ process.env.BROWSERSTACK_ACCESS_KEY = rawCaps.accessKey
87
+
88
+ console.log('capabilities.platformName:', rawCaps.platformName ?? 'web');
89
+ const isMobile = rawCaps.platformName === "android" || rawCaps.platformName === "ios";
90
+ process.env.BS_SESSION_TYPE = isMobile ? 'app-automate' : 'automate';
91
+
92
+ rawCaps.buildName = process.env.FROTH_TESTOPS_BUILD_NAME;
93
+ console.log("SessionType=====>:", process.env.BS_SESSION_TYPE);
105
94
 
106
95
  }
107
96
 
108
97
  }
109
98
 
110
- setupPrerequisites();
111
-
112
- // =====================================================
113
- // IMPORTANT: NORMALIZE CAPABILITY FUNCTION
114
- // =====================================================
115
- function normalizeCapabilities(rawCaps, sessionType, platform) {
116
- if (platform === "browserstack") {
117
- // ----------------------------------
118
- // BrowserStack Automate (Web)
119
- // ----------------------------------
120
- if (sessionType === "automate") {
121
- return {
122
- browserName: rawCaps.browserName,
123
- browserVersion: rawCaps.browserVersion,
124
- 'bstack:options': {
125
- os: rawCaps.os,
126
- osVersion: rawCaps.osVersion,
127
- consoleLogs: rawCaps.consoleLogs,
128
- networkLogs: rawCaps.networkLogs,
129
- debug: rawCaps.debug,
130
- interactiveDebugging: rawCaps.interactiveDebugging,
131
- buildIdentifier: rawCaps.buildIdentifier,
132
- // userName: rawCaps.userName,
133
- // accessKey: process.env.BROWSERSTACK_ACCESS_KEY
134
- }
135
- };
136
- }
99
+ setupPrerequisites(rawCaps);
100
+ // ---------------------------------------------
101
+ // NORMALIZER — WEB + MOBILE (AUTODETECTION)
102
+ // ---------------------------------------------
103
+ function normalizeCapabilities(raw) {
104
+ const isMobile =
105
+ raw.platformName === "android" || raw.platformName === "ios";
106
+ const isWeb = !!raw.browserName;
107
+
108
+ // --------------------------
109
+ // 1. MOBILE App Automate
110
+ // --------------------------
111
+ if (isMobile) {
112
+
113
+ return {
114
+ platformName: raw.platformName,
115
+ "appium:platformVersion": raw.platformVersion,
116
+ "appium:deviceName": raw.deviceName,
117
+ "appium:deviceOrientation": raw.deviceOrientation,
118
+ "bstack:options": {
119
+ userName: raw.userName,
120
+ accessKey: Buffer.from(raw.accessKey, "base64").toString("utf8"),
121
+ debug: raw.debug,
122
+ networkLogs: raw.networkLogs,
123
+ interactiveDebugging: raw.interactiveDebugging,
124
+ // appProfiling: raw.appProfiling,
125
+ buildIdentifier: raw.buildIdentifier,
126
+ // sessionType: "app",
127
+ appiumVersion: "2.0",
128
+ projectName: process.env.BS_PROJECT_NAME || "Automation",
129
+ buildName: process.env.FROTH_TESTOPS_BUILD_NAME || "Mobile Build",
130
+ }
131
+ };
132
+ }
133
+ if (isWeb) {
134
+
135
+ // --------------------------
136
+ // 2. WEB – Browser Automate
137
+ // --------------------------
137
138
 
138
- // ----------------------------------
139
- // BrowserStack APP-Automate (Mobile)
140
- // ----------------------------------
141
139
  return {
142
- platformName: rawCaps.platformName,
143
- 'appium:platformVersion': rawCaps.platformVersion,
144
- 'appium:deviceName': rawCaps.deviceName,
145
- 'appium:deviceOrientation': rawCaps.deviceOrientation,
146
- 'appium:app': rawCaps.app || "",
147
- 'bstack:options': {
148
- // appProfiling: rawCaps.appProfiling,
149
- networkLogs: rawCaps.networkLogs,
150
- debug: rawCaps.debug,
151
- interactiveDebugging: rawCaps.interactiveDebugging,
152
- buildIdentifier: rawCaps.buildIdentifier,
153
-
154
- // userName: rawCaps.userName,
155
- // accessKey: process.env.BROWSERSTACK_ACCESS_KEY
140
+ browserName: raw.browserName,
141
+ browserVersion: raw.browserVersion || "latest",
142
+ "bstack:options": {
143
+ os: raw.os || "Windows",
144
+ osVersion: raw.osVersion || "11",
145
+ userName: raw.userName,
146
+ accessKey: Buffer.from(raw.accessKey, "base64").toString("utf8"),
147
+ debug: raw.debug !== false,
148
+ networkLogs: raw.networkLogs !== false,
149
+ // sessionType: "automate",
150
+ projectName: process.env.BS_PROJECT_NAME || "Automation",
151
+ buildName: process.env.FROTH_TESTOPS_BUILD_NAME || "Web Build",
156
152
  }
157
153
  };
158
154
  }
159
- return rawCaps;
160
155
 
156
+ throw new Error("❌ YAML does not look like web or mobile capability");
161
157
  }
162
- const normalizedCaps = normalizeCapabilities(capabilities, process.env.BS_SESSION_TYPE, PLATFORM);
163
- console.log("====> Final WDIO Normalised Capabilities:", normalizedCaps);
158
+ const finalCaps =
159
+ PLATFORM === "browserstack" ? normalizeCapabilities(rawCaps) : rawCaps;
160
+
161
+ console.log("==== FINAL CAPS SENT TO BROWSERSTACK ====");
162
+ console.log(JSON.stringify(finalCaps, null, 2));
164
163
 
165
164
  exports.config = deepmerge(commonconfig,
166
165
 
@@ -169,23 +168,17 @@ exports.config = deepmerge(commonconfig,
169
168
  key: process.env.BROWSERSTACK_ACCESS_KEY,
170
169
  // debug: true,
171
170
  // execArgv: ['--inspect-brk'],
172
- // services: PLATFORM === 'browserstack'
173
- // ? [['browserstack', { browserstackLocal: false }]]
174
- // : PLATFORM === 'saucelabs'
175
- // ? ['sauce']
176
- // : [],
177
-
178
- services: [
179
- [
180
- 'browserstack',
181
- { browserstackLocal: false, opts: { forcelocal: false } },
182
- ],
183
- ],
171
+ services: PLATFORM === 'browserstack'
172
+ ? [['browserstack', { browserstackLocal: false }]]
173
+ : PLATFORM === 'saucelabs'
174
+ ? ['sauce']
175
+ : [],
176
+
184
177
  //runner: 'local',
185
178
  specs: require(SUITE_FILE).tests,
186
179
 
187
180
  maxInstances: 1,
188
- capabilities: [normalizedCaps],
181
+ capabilities: [finalCaps],
189
182
 
190
183
  logLevel: 'info',
191
184
  coloredLogs: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "froth-webdriverio-framework",
3
- "version": "6.0.7",
3
+ "version": "6.0.9",
4
4
  "readme": "WebdriverIO Integration",
5
5
  "description": "WebdriverIO and BrowserStack App Automate",
6
6
  "license": "MIT",