froth-webdriverio-framework 6.0.84 → 6.0.85

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.
@@ -134,7 +134,7 @@ async function updateExecuitonDetails(frothUrl, token, id, resultdetails) {
134
134
  formData.append('excution_time', resultdetails.excution_time);
135
135
  }
136
136
 
137
- if (Array.isArray(resultdetails.comments) && resultdetails.comments.length) {
137
+ if (Array.isArray(resultdetails.comments) && resultdetails.comments.length!=0) {
138
138
  formData.append('comments', resultdetails.comments.join('<br>'));
139
139
  }
140
140
 
@@ -41,7 +41,7 @@ let scrollIntoView = null;
41
41
  let api = null;
42
42
 
43
43
  let selectDropDownValue = null;
44
- let selectDropDownText = null;
44
+ let selectDropDownText = null;
45
45
 
46
46
  let acceptAlert = null;
47
47
  let dismissAlert = null;
@@ -106,16 +106,16 @@ api = require(basepath + '/apicall').callapi;
106
106
  validate = require(basepath + '/apicall').validate;
107
107
 
108
108
  selectDropDownValue = require(basepath + '/dropDown').select4mDropDownValue;
109
- selectDropDownText= require(basepath + '/dropDown').select4mDropDownText;
109
+ selectDropDownText = require(basepath + '/dropDown').select4mDropDownText;
110
110
 
111
111
  acceptAlert = require(basepath + '/alert.js').acceptalert;
112
112
  dismissAlert = require(basepath + '/alert.js').dismissalert;
113
113
 
114
114
  generateJWT = require(basepath + '/jwt').generateJWTToken;
115
- captureLoadNavigation= require(basepath + '/captureNavigationTime').captureLoadNavigationTime;
115
+ captureLoadNavigation = require(basepath + '/captureNavigationTime').captureLoadNavigationTime;
116
116
 
117
- amendBrowserStackLog= require(basepath + '/../froth_api_calls/browsersatckSessionInfo').amend2Browserstack;
118
- logJsonDataToTable= require(basepath + '/logData').logJsonData2Table;
117
+ amendBrowserStackLog = require(basepath + '/../froth_api_calls/browsersatckSessionInfo').amend2Browserstack;
118
+ logJsonDataToTable = require(basepath + '/logData').logJsonData2Table;
119
119
 
120
120
  //extractEmailLinks = require(basepath + '/emailParsing');
121
121
  //export the variabels
@@ -163,5 +163,5 @@ module.exports = {
163
163
  captureLoadNavigation,
164
164
  amendBrowserStackLog,
165
165
  logJsonDataToTable,
166
- // extractEmailLinks
166
+ extractEmailLinks
167
167
  };
@@ -0,0 +1,161 @@
1
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
2
+
3
+ const Imap = require('imap');
4
+ const { simpleParser } = require('mailparser');
5
+ const cheerio = require('cheerio');
6
+
7
+ /**
8
+ * Connects to an IMAP inbox, parses emails, and extracts all unique links.
9
+ * @param {Object} config - IMAP config { user, password, host, port, tls }
10
+ * @param {Object} [filter] - Optional filter { subject, from }
11
+ * @returns {Promise<Array<{link: string, text: string}>>}
12
+ */
13
+ async function getEmailLinks(username,app_password, subjectdetails,fromemail) {
14
+ const config = {
15
+ user: username,
16
+ password: app_password,
17
+ host: 'imap.gmail.com',
18
+ port: 993,
19
+ tls: true
20
+ };
21
+ const filter = {
22
+ subject: subjectdetails,
23
+ from: fromemail
24
+ };
25
+ const imap = new Imap(config);
26
+
27
+ function openInbox(cb) {
28
+ imap.openBox('INBOX', true, cb);
29
+ }
30
+
31
+ return new Promise((resolve, reject) => {
32
+ let results = new Map();
33
+ let allLinks = [];
34
+ let parseDone;
35
+ const parsePromise = new Promise(res => { parseDone = res; });
36
+
37
+ imap.once('ready', function () {
38
+ openInbox(function (err, box) {
39
+ if (err) return cleanup(err);
40
+
41
+ // Build search criteria
42
+ let searchCriteria = ['ALL'];
43
+ if (filter.subject) searchCriteria.push(['HEADER', 'SUBJECT', filter.subject]);
44
+ if (filter.from) searchCriteria.push(['FROM', filter.from]);
45
+
46
+ imap.search(searchCriteria, function (err, uids) {
47
+ if (err) return cleanup(err);
48
+ if (!uids.length) return cleanup(null, []);
49
+
50
+ // Sort UIDs descending to get the latest email first
51
+ uids = uids.sort((a, b) => b - a);
52
+ // Only fetch the latest email
53
+ const latestUid = uids[0];
54
+ const fetch = imap.fetch([latestUid], { bodies: '' });
55
+ fetch.on('message', function (msg) {
56
+ let buffer = '';
57
+ msg.on('body', function (stream) {
58
+ stream.on('data', function (chunk) {
59
+ buffer += chunk.toString('utf8');
60
+ });
61
+ });
62
+ msg.once('end', async function () {
63
+ try {
64
+ const parsed = await simpleParser(buffer);
65
+ let links = [];
66
+
67
+ // Extract from HTML with element context
68
+ if (parsed.html) {
69
+ const $ = cheerio.load(parsed.html);
70
+ $('a[href], button[href], [role="button"][href], img[src], area[href]').each((_, el) => {
71
+ let link = null;
72
+ let text = '';
73
+ let elementType = el.tagName;
74
+ if (elementType === 'a' || elementType === 'area') {
75
+ link = $(el).attr('href');
76
+ text = $(el).text().trim() || link;
77
+ } else if (elementType === 'img') {
78
+ link = $(el).attr('src');
79
+ text = $(el).attr('alt') || link;
80
+ } else if (elementType === 'button' || $(el).attr('role') === 'button') {
81
+ link = $(el).attr('href');
82
+ text = $(el).text().trim() || link;
83
+ }
84
+ if (link) {
85
+ links.push({ link, text, element: elementType });
86
+ }
87
+ });
88
+ }
89
+
90
+ // Extract from plaintext
91
+ if (parsed.text) {
92
+ const urlRegex = /(https?:\/\/[^\s]+)/g;
93
+ let match;
94
+ while ((match = urlRegex.exec(parsed.text))) {
95
+ links.push({ link: match[1], text: match[1], element: 'text' });
96
+ }
97
+ }
98
+
99
+ // Deduplicate by link and element context
100
+ for (const l of links) {
101
+ const key = l.link + '|' + l.element + '|' + l.text;
102
+ if (!results.has(key)) {
103
+ results.set(key, { link: l.link, text: l.text, element: l.element });
104
+ }
105
+ }
106
+ allLinks = Array.from(results.values());
107
+ parseDone();
108
+ } catch (e) {
109
+ // Log and continue
110
+ console.error('Parse error:', e);
111
+ parseDone();
112
+ }
113
+ });
114
+ });
115
+ fetch.once('error', cleanup);
116
+ fetch.once('end', async () => {
117
+ await parsePromise;
118
+ cleanup(null, allLinks);
119
+ });
120
+ });
121
+ });
122
+ });
123
+
124
+ imap.once('error', cleanup);
125
+
126
+ function cleanup(err, data) {
127
+ imap.end();
128
+ if (err) reject(err);
129
+ else resolve(data);
130
+ }
131
+
132
+ imap.connect();
133
+ });
134
+ }
135
+
136
+ async function findLinks(links,searchText) {
137
+ const findLinkByText = (links, searchText) => {
138
+ return links.find(l => l.text && l.text.toLowerCase().includes(searchText.toLowerCase()));
139
+ };
140
+ // Example usage:
141
+ const found = findLinkByText(links, searchText);
142
+ return found ? found.link : null;
143
+ }
144
+
145
+
146
+ // Example main function for direct execution
147
+ // if (require.main === module) {
148
+ // (async () => {
149
+
150
+ // const links = await extractEmailLinks('gfntesting44@gmail.com','wtrd qfee dicr hpba', "GFN Testing, review your Google Account settings","no-reply@google.com");
151
+ // console.log('Extracted links in main:', links);
152
+ // const foundLink = await findLinks(links,"Privacy Policy");
153
+ // console.log('Found Link: ', foundLink);
154
+
155
+
156
+ // })();
157
+
158
+ // }
159
+
160
+ module.exports = { getEmailLinks ,findLinks}
161
+
@@ -258,7 +258,8 @@ const commonHooks = {
258
258
  afterSession: async (config, capabilities, specs, exitCode) => {
259
259
  console.log('==== AFTER SESSION ====');
260
260
  // Do not calculate time here; we will use WDIO's total duration in onComplete
261
- console.log('⏱ Leaving execution time calculation for onComplete hook');
261
+ console.log('⏱ Leaving execution time calculation for onComplete hook'+resultdetails.comments);
262
+
262
263
 
263
264
  },
264
265
 
@@ -298,7 +299,7 @@ const commonHooks = {
298
299
 
299
300
  // resultdetails.comments = allComments;
300
301
 
301
- console.log('Comments being sent:', resultdetails.comments);
302
+ console.log('Comments being sent:', resultdetails.comments.length==0?'':JSON.stringify(resultdetails.comments));
302
303
  console.log('⏱ Final execution time (ms):', totalTime);
303
304
  console.log('⏱ Final execution time (hh:mm:ss):', resultdetails.excution_time);
304
305
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "froth-webdriverio-framework",
3
- "version": "6.0.84",
3
+ "version": "6.0.85",
4
4
  "readme": "WendriverIO Integration with [BrowserStack](https://www.browserstack.com)",
5
5
  "description": "Selenium examples for WebdriverIO and BrowserStack App Automate",
6
6
  "scripts": {