vita-playwright 0.1.1
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/.prettierrc +9 -0
- package/README.md +617 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/src/helpers/api-helpers.d.ts +5 -0
- package/dist/src/helpers/api-helpers.js +52 -0
- package/dist/src/helpers/api-helpers.js.map +1 -0
- package/dist/src/helpers/ui-helpers.d.ts +24 -0
- package/dist/src/helpers/ui-helpers.js +172 -0
- package/dist/src/helpers/ui-helpers.js.map +1 -0
- package/dist/src/utils/api_axios.d.ts +5 -0
- package/dist/src/utils/api_axios.js +35 -0
- package/dist/src/utils/api_axios.js.map +1 -0
- package/dist/src/utils/azure_storage_methods.d.ts +4 -0
- package/dist/src/utils/azure_storage_methods.js +130 -0
- package/dist/src/utils/azure_storage_methods.js.map +1 -0
- package/dist/src/utils/comparisions.d.ts +12 -0
- package/dist/src/utils/comparisions.js +98 -0
- package/dist/src/utils/comparisions.js.map +1 -0
- package/dist/src/utils/date_utilitites.d.ts +9 -0
- package/dist/src/utils/date_utilitites.js +30 -0
- package/dist/src/utils/date_utilitites.js.map +1 -0
- package/dist/src/utils/document_utility.d.ts +8 -0
- package/dist/src/utils/document_utility.js +77 -0
- package/dist/src/utils/document_utility.js.map +1 -0
- package/dist/src/utils/email_sender.d.ts +14 -0
- package/dist/src/utils/email_sender.js +58 -0
- package/dist/src/utils/email_sender.js.map +1 -0
- package/dist/src/utils/keyvault_methods.d.ts +3 -0
- package/dist/src/utils/keyvault_methods.js +30 -0
- package/dist/src/utils/keyvault_methods.js.map +1 -0
- package/dist/src/utils/lighhouse_utility.d.ts +12 -0
- package/dist/src/utils/lighhouse_utility.js +132 -0
- package/dist/src/utils/lighhouse_utility.js.map +1 -0
- package/dist/src/utils/test_data.d.ts +9 -0
- package/dist/src/utils/test_data.js +142 -0
- package/dist/src/utils/test_data.js.map +1 -0
- package/dist/src/utils/xmlToJson.d.ts +3 -0
- package/dist/src/utils/xmlToJson.js +57 -0
- package/dist/src/utils/xmlToJson.js.map +1 -0
- package/index.ts +25 -0
- package/package.json +58 -0
- package/src/helpers/api-helpers.ts +38 -0
- package/src/helpers/ui-helpers.ts +148 -0
- package/src/utils/api_axios.ts +16 -0
- package/src/utils/azure_storage_methods.ts +171 -0
- package/src/utils/comparisions.ts +99 -0
- package/src/utils/date_utilitites.ts +39 -0
- package/src/utils/document_utility.ts +81 -0
- package/src/utils/email_sender.ts +36 -0
- package/src/utils/keyvault_methods.ts +15 -0
- package/src/utils/lighhouse_utility.ts +123 -0
- package/src/utils/test_data.ts +121 -0
- package/src/utils/xmlToJson.ts +41 -0
- package/tsconfig.json +106 -0
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vita-playwright",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"email": "noreply_testautomation@vialto.com",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"publish": "npm run build && npm publish --access public",
|
|
10
|
+
"prettier": "prettier --write \"**/*.ts\""
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@azure/storage-blob": "^12.11.0",
|
|
14
|
+
"@cucumber/cucumber": "7.3.1",
|
|
15
|
+
"@cucumber/html-formatter": "11.0.4",
|
|
16
|
+
"@cucumber/pretty-formatter": "1.0.0-alpha.0",
|
|
17
|
+
"@playwright/test": "^1.39.0",
|
|
18
|
+
"@types/lodash": "4.14.189",
|
|
19
|
+
"@types/node": "18.11.9",
|
|
20
|
+
"@typescript-eslint/eslint-plugin": "5.43.0",
|
|
21
|
+
"@typescript-eslint/parser": "5.43.0",
|
|
22
|
+
"allure-commandline": "^2.20.1",
|
|
23
|
+
"allure-cucumberjs": "2.0.0-beta.21",
|
|
24
|
+
"allure-playwright": "^2.0.0-beta.20",
|
|
25
|
+
"axios": "^0.27.2",
|
|
26
|
+
"crypto-js": "^4.1.1",
|
|
27
|
+
"cucumber-console-formatter": "1.0.0",
|
|
28
|
+
"dotenv": "^16.0.3",
|
|
29
|
+
"eslint": "8.28.0",
|
|
30
|
+
"eslint-config-prettier": "8.5.0",
|
|
31
|
+
"eslint-plugin-import": "2.26.0",
|
|
32
|
+
"eslint-plugin-prettier": "4.2.1",
|
|
33
|
+
"is-ci": "2.0.0",
|
|
34
|
+
"lighthouse": "^9.6.8",
|
|
35
|
+
"lodash": "^4.17.21",
|
|
36
|
+
"moment": "^2.29.4",
|
|
37
|
+
"mssql": "9.0.0",
|
|
38
|
+
"nodemailer": "^6.9.1",
|
|
39
|
+
"open": "8.4.0",
|
|
40
|
+
"pdfreader": "^3.0.0",
|
|
41
|
+
"playwright": "^1.25.0",
|
|
42
|
+
"playwright-lighthouse": "^2.2.2",
|
|
43
|
+
"prettier": "2.7.1",
|
|
44
|
+
"rimraf": "3.0.2",
|
|
45
|
+
"ts-node": "10.9.1",
|
|
46
|
+
"typescript": "4.9.3",
|
|
47
|
+
"xlsx": "^0.18.5",
|
|
48
|
+
"xmldom": "0.6.0"
|
|
49
|
+
},
|
|
50
|
+
"author": "Vialto QE",
|
|
51
|
+
"license": "ISC",
|
|
52
|
+
"description": "common functions for playwright and nodejs",
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "https://github.com/Vialto/vialto-test-automation/",
|
|
56
|
+
"homepage": "https://github.com/Vialto/vialto-test-automation/#readme"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { TokenGenerators } from '../utils/api_axios';
|
|
2
|
+
|
|
3
|
+
export class ApiHelper {
|
|
4
|
+
static async post(url: any, header: any, payload: any) {
|
|
5
|
+
const config = {
|
|
6
|
+
method: 'post',
|
|
7
|
+
url: url,
|
|
8
|
+
headers: header,
|
|
9
|
+
data: payload,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const response = await TokenGenerators.request(config);
|
|
13
|
+
return response;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static async get(url: any, header: any) {
|
|
17
|
+
const config = {
|
|
18
|
+
method: 'GET',
|
|
19
|
+
url: url,
|
|
20
|
+
headers: header,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const response = await TokenGenerators.request(config);
|
|
24
|
+
return response;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static async put(url: any, header: any, payload: any) {
|
|
28
|
+
const config = {
|
|
29
|
+
method: 'put',
|
|
30
|
+
url: url,
|
|
31
|
+
headers: header,
|
|
32
|
+
data: payload,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const response = await TokenGenerators.request(config);
|
|
36
|
+
return response;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
//import robot from "robotjs";
|
|
2
|
+
import { BrowserContext, chromium } from 'playwright';
|
|
3
|
+
export class UIHelper {
|
|
4
|
+
page: any;
|
|
5
|
+
browser: BrowserContext;
|
|
6
|
+
|
|
7
|
+
constructor(page: any) {
|
|
8
|
+
this.page = page;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* chromePath should be something like below
|
|
12
|
+
<UserDirectory>/AppData/Local/Google/Chrome/User Data
|
|
13
|
+
*/
|
|
14
|
+
async launchNonIncognito(chromePath: string) {
|
|
15
|
+
// Launch non-incognito session using provided chromePath
|
|
16
|
+
this.browser = await chromium.launchPersistentContext(chromePath, {
|
|
17
|
+
headless: false,
|
|
18
|
+
});
|
|
19
|
+
this.page = await this.browser.newPage();
|
|
20
|
+
this.browser.clearCookies();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Close All the windows opened for non-incognito session
|
|
24
|
+
async closeNonIncognito() {
|
|
25
|
+
this.browser.clearCookies();
|
|
26
|
+
const allPages = this.browser.pages();
|
|
27
|
+
allPages.forEach((element) => {
|
|
28
|
+
element.close();
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//Combines given list of cookies and generates a single cookie for passing in API as header
|
|
33
|
+
combineAllCookies(cookieJson) {
|
|
34
|
+
let Finalcookie: string = '';
|
|
35
|
+
for (let val of cookieJson) {
|
|
36
|
+
Finalcookie += val.name + '=' + val.value + ';';
|
|
37
|
+
}
|
|
38
|
+
console.log(
|
|
39
|
+
'\n----------------> Final Cookie Generated ---------------->\n'
|
|
40
|
+
);
|
|
41
|
+
Finalcookie = Finalcookie.toString().slice(0, -1);
|
|
42
|
+
return Finalcookie.toString();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async filltheData(locator: any, data: any) {
|
|
46
|
+
if (data) {
|
|
47
|
+
await this.waitTillElementIsVisible(locator);
|
|
48
|
+
await this.page.locator(locator).scrollIntoViewIfNeeded();
|
|
49
|
+
await this.page.locator(locator).fill(data);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async clickonWebElement(locator: any) {
|
|
54
|
+
await this.page.locator(locator).scrollIntoViewIfNeeded();
|
|
55
|
+
await this.waitTillElementIsVisible(locator);
|
|
56
|
+
await this.page.locator(locator).click();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async getInnerHTML(locator: any) {
|
|
60
|
+
await this.waitTillElementIsVisible(locator);
|
|
61
|
+
await this.page.locator(locator).scrollIntoViewIfNeeded();
|
|
62
|
+
return await this.page.innerHTML(locator);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async getInnerText(locator: any) {
|
|
66
|
+
await this.waitTillElementIsVisible(locator);
|
|
67
|
+
await this.page.locator(locator).scrollIntoViewIfNeeded();
|
|
68
|
+
return await this.page.locator(locator).innerText().trim();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async getText(locator: any) {
|
|
72
|
+
await this.waitTillElementIsVisible(locator);
|
|
73
|
+
await this.page.locator(locator).scrollIntoViewIfNeeded();
|
|
74
|
+
return await this.page.locator(locator).textContent();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async getAttribute(locator: any, attribute: any) {
|
|
78
|
+
await this.waitTillElementIsVisible(locator);
|
|
79
|
+
await this.page.locator(locator).scrollIntoViewIfNeeded();
|
|
80
|
+
return await this.page.locator(locator).getAttribute(attribute);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async evaluateJS(jsDOM: any) {
|
|
84
|
+
return await this.page.evaluate(jsDOM);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async isElementPresent(locator: any) {
|
|
88
|
+
// console.log(typeof locator.toString());
|
|
89
|
+
let type = typeof locator;
|
|
90
|
+
if (type === 'string') {
|
|
91
|
+
await this.page.locator(locator).scrollIntoViewIfNeeded();
|
|
92
|
+
return await this.page.locator(locator).isVisible();
|
|
93
|
+
} else if (type === 'object') {
|
|
94
|
+
return await locator.isVisible();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.log(type);
|
|
98
|
+
console.log(type.toString());
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async isElementEnabled(locator: any) {
|
|
102
|
+
await this.page.locator(locator).scrollIntoViewIfNeeded();
|
|
103
|
+
return await this.page.locator(locator).isEnabled();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async waitTillElementIsVisible(elementSelector: any, waitTime = 60000) {
|
|
107
|
+
await this.page.waitForSelector(elementSelector, {
|
|
108
|
+
waitFor: 'visible',
|
|
109
|
+
timeout: waitTime,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async getInputBoxValue(locator: any) {
|
|
114
|
+
await this.waitTillElementIsVisible(locator);
|
|
115
|
+
await this.page.locator(locator).scrollIntoViewIfNeeded();
|
|
116
|
+
return await this.page.inputValue();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// async closeCertificationPopup() {
|
|
120
|
+
// await this.page.waitForTimeout(5000);
|
|
121
|
+
// robot.moveMouse(400, 20);
|
|
122
|
+
// robot.keyTap("enter");
|
|
123
|
+
// }
|
|
124
|
+
|
|
125
|
+
async downloadAFile(downloadButton: String, filePath: string) {
|
|
126
|
+
const downloadPromise = this.page.waitForEvent('download');
|
|
127
|
+
await this.clickonWebElement(downloadButton);
|
|
128
|
+
const download = await downloadPromise;
|
|
129
|
+
// Wait for the download process to complete
|
|
130
|
+
console.log('download', await download.path());
|
|
131
|
+
await download.saveAs(filePath);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async uploadAFile(uploadButton: String, uploadFilePath: String) {
|
|
135
|
+
const fileChooserPromise = this.page.waitForEvent('filechooser');
|
|
136
|
+
await this.clickonWebElement(uploadButton);
|
|
137
|
+
const fileChooser = await fileChooserPromise;
|
|
138
|
+
await fileChooser.setFiles(uploadFilePath);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async getElementRefByRole(roleType: string, roleName: string) {
|
|
142
|
+
return this.page.getByRole(roleType, { name: roleName });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async getElementLocatorByText(text: string) {
|
|
146
|
+
return this.page.getByText(text, { exact: true });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import axios, { AxiosRequestConfig } from 'axios';
|
|
2
|
+
|
|
3
|
+
export class TokenGenerators {
|
|
4
|
+
static generateKeyVaultAccessToken() {
|
|
5
|
+
throw new Error('Method not implemented.');
|
|
6
|
+
}
|
|
7
|
+
static async request(config: AxiosRequestConfig<any>) {
|
|
8
|
+
try {
|
|
9
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
10
|
+
const response = await axios(config);
|
|
11
|
+
return response;
|
|
12
|
+
} catch (error) {
|
|
13
|
+
return error.response;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { DOMParser } from 'xmldom';
|
|
2
|
+
import { XmlToJson } from './xmlToJson';
|
|
3
|
+
import HmacSHA256 from 'crypto-js/hmac-sha256';
|
|
4
|
+
import Base64 from 'crypto-js/enc-base64';
|
|
5
|
+
import { TokenGenerators } from './api_axios';
|
|
6
|
+
import { BlobServiceClient } from '@azure/storage-blob';
|
|
7
|
+
export class AzureStorageMethods {
|
|
8
|
+
static async getblobs(
|
|
9
|
+
storageAccount: any,
|
|
10
|
+
containerName: any,
|
|
11
|
+
storageAccountKey: any,
|
|
12
|
+
apiMethodName: string,
|
|
13
|
+
blobFilterName = ''
|
|
14
|
+
) {
|
|
15
|
+
const header_date = new Date().toUTCString();
|
|
16
|
+
const apiMethod = apiMethodName.toUpperCase();
|
|
17
|
+
|
|
18
|
+
const url = new URL(
|
|
19
|
+
`https://${storageAccount}.blob.core.windows.net/${containerName}?restype=container&comp=list&prefix=${blobFilterName}`
|
|
20
|
+
);
|
|
21
|
+
const signatureParts = [
|
|
22
|
+
apiMethod,
|
|
23
|
+
'',
|
|
24
|
+
'',
|
|
25
|
+
'',
|
|
26
|
+
'',
|
|
27
|
+
'',
|
|
28
|
+
'',
|
|
29
|
+
'',
|
|
30
|
+
'',
|
|
31
|
+
'',
|
|
32
|
+
'',
|
|
33
|
+
'',
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const canonicalHeaderParts = [];
|
|
37
|
+
canonicalHeaderParts.push(`x-ms-date:${header_date}`);
|
|
38
|
+
canonicalHeaderParts.push(`x-ms-version:2018-03-28`);
|
|
39
|
+
|
|
40
|
+
// Add headers to signature
|
|
41
|
+
signatureParts.push.apply(signatureParts, canonicalHeaderParts);
|
|
42
|
+
|
|
43
|
+
// Construct CanonicalizedResource
|
|
44
|
+
const canonicalResourceParts = [`/${storageAccount}${url.pathname}`];
|
|
45
|
+
const canonicalQueryNames: string[] = [];
|
|
46
|
+
url.searchParams.forEach((value, key) => {
|
|
47
|
+
canonicalQueryNames.push(key.toLowerCase());
|
|
48
|
+
});
|
|
49
|
+
canonicalQueryNames.sort();
|
|
50
|
+
canonicalQueryNames.forEach((queryName) => {
|
|
51
|
+
const value = url.searchParams.get(queryName);
|
|
52
|
+
|
|
53
|
+
canonicalResourceParts.push(`${queryName}:${value}`);
|
|
54
|
+
});
|
|
55
|
+
// Add resource to signature
|
|
56
|
+
signatureParts.push.apply(signatureParts, canonicalResourceParts);
|
|
57
|
+
|
|
58
|
+
// Now, construct signature raw string
|
|
59
|
+
const signatureRaw = signatureParts.join('\n');
|
|
60
|
+
|
|
61
|
+
// Hash it using HMAC-SHA256 and then encode using base64
|
|
62
|
+
|
|
63
|
+
const signatureBytes = HmacSHA256(
|
|
64
|
+
signatureRaw,
|
|
65
|
+
Base64.parse(storageAccountKey)
|
|
66
|
+
);
|
|
67
|
+
const signatureEncoded = signatureBytes.toString(Base64);
|
|
68
|
+
|
|
69
|
+
const config = {
|
|
70
|
+
method: apiMethod,
|
|
71
|
+
url: `https://${storageAccount}.blob.core.windows.net/${containerName}?restype=container&comp=list&prefix=${blobFilterName}`,
|
|
72
|
+
headers: {
|
|
73
|
+
Authorization: `SharedKey ${storageAccount}:${signatureEncoded}`,
|
|
74
|
+
'x-ms-date': header_date,
|
|
75
|
+
'x-ms-version': '2018-03-28',
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const response = await TokenGenerators.request(config);
|
|
80
|
+
const apiData = response.data;
|
|
81
|
+
const XmlNode = new DOMParser().parseFromString(apiData, 'text/xml');
|
|
82
|
+
const jsonObj = await XmlToJson.xmlToJson(XmlNode);
|
|
83
|
+
const blobs = jsonObj.EnumerationResults.Blobs.Blob;
|
|
84
|
+
const newBlobs = [];
|
|
85
|
+
if (blobs.length) {
|
|
86
|
+
for (let i = 0; i < blobs.length; i++) {
|
|
87
|
+
const blob = {
|
|
88
|
+
fileName: blobs[i].Name['#text'].replace(
|
|
89
|
+
blobFilterName,
|
|
90
|
+
''
|
|
91
|
+
),
|
|
92
|
+
modifiedTime: Date.parse(
|
|
93
|
+
blobs[i].Properties['Last-Modified']['#text']
|
|
94
|
+
),
|
|
95
|
+
status:
|
|
96
|
+
Math.floor(
|
|
97
|
+
Date.now() -
|
|
98
|
+
Date.parse(
|
|
99
|
+
blobs[i].Properties['Last-Modified'][
|
|
100
|
+
'#text'
|
|
101
|
+
]
|
|
102
|
+
) /
|
|
103
|
+
1000
|
|
104
|
+
) > 30
|
|
105
|
+
? 1
|
|
106
|
+
: 0,
|
|
107
|
+
};
|
|
108
|
+
newBlobs.push(blob);
|
|
109
|
+
}
|
|
110
|
+
} else if (blobs.fileName) {
|
|
111
|
+
const blob = {
|
|
112
|
+
fileName: blobs.Name['#text'].replace(blobFilterName, ''),
|
|
113
|
+
modifiedTime: Date.parse(
|
|
114
|
+
blobs.Properties['Last-Modified']['#text']
|
|
115
|
+
),
|
|
116
|
+
status:
|
|
117
|
+
Math.floor(
|
|
118
|
+
Date.now() -
|
|
119
|
+
Date.parse(
|
|
120
|
+
blobs.Properties['Last-Modified']['#text']
|
|
121
|
+
) /
|
|
122
|
+
1000
|
|
123
|
+
) > 30
|
|
124
|
+
? 1
|
|
125
|
+
: 0,
|
|
126
|
+
};
|
|
127
|
+
newBlobs.push(blob);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
newBlobs.sort((a, b) =>
|
|
131
|
+
a.fileName > b.fileName ? 1 : b.fileName > a.fileName ? -1 : 0
|
|
132
|
+
);
|
|
133
|
+
newBlobs.sort((a, b) =>
|
|
134
|
+
a.modifiedTime < b.modifiedTime
|
|
135
|
+
? 1
|
|
136
|
+
: b.modifiedTime < a.modifiedTime
|
|
137
|
+
? -1
|
|
138
|
+
: 0
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
return newBlobs;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static async createBlobByUploadingData(
|
|
145
|
+
storageAccount: string,
|
|
146
|
+
sasToken: string,
|
|
147
|
+
containerName: string,
|
|
148
|
+
filepath: string,
|
|
149
|
+
fileNameWithExtension: string
|
|
150
|
+
) {
|
|
151
|
+
const blobServiceClient = new BlobServiceClient(
|
|
152
|
+
'https://' +
|
|
153
|
+
storageAccount +
|
|
154
|
+
'.blob.core.windows.net/' +
|
|
155
|
+
'?' +
|
|
156
|
+
sasToken
|
|
157
|
+
);
|
|
158
|
+
const containerClient =
|
|
159
|
+
blobServiceClient.getContainerClient(containerName);
|
|
160
|
+
|
|
161
|
+
const blockBlobClient = containerClient.getBlockBlobClient(
|
|
162
|
+
fileNameWithExtension
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
const uploadBlobResponse = await blockBlobClient.uploadFile(filepath);
|
|
166
|
+
|
|
167
|
+
console.log(
|
|
168
|
+
`Block blob ${fileNameWithExtension} uploaded successfully`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { expect } from '@playwright/test';
|
|
2
|
+
import { isDeepStrictEqual } from 'util';
|
|
3
|
+
import _ from 'lodash';
|
|
4
|
+
|
|
5
|
+
export class Comparisions {
|
|
6
|
+
static async compareObjects(actualObj: string, expectedObj: string) {
|
|
7
|
+
let same;
|
|
8
|
+
console.log(
|
|
9
|
+
'Actual Obj: ' + actualObj + ' and Expected Obj: ' + expectedObj
|
|
10
|
+
);
|
|
11
|
+
same = _.isEqual(actualObj, expectedObj);
|
|
12
|
+
console.log(same);
|
|
13
|
+
return same;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static async compareUnorderedJSONObjects(
|
|
17
|
+
actualObj: { [x: string]: any },
|
|
18
|
+
expectedObj: { [x: string]: any }
|
|
19
|
+
) {
|
|
20
|
+
const Keydata = Object.keys(expectedObj);
|
|
21
|
+
const result = new Array();
|
|
22
|
+
let boolean;
|
|
23
|
+
for (let i = 0; i < Keydata.length; i++) {
|
|
24
|
+
if (actualObj[Keydata[i]] == expectedObj[Keydata[i]]) {
|
|
25
|
+
result.push(true);
|
|
26
|
+
} else {
|
|
27
|
+
result.push(false);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
boolean = result.includes(false) ? false : true;
|
|
31
|
+
return boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static areJsonFilesEqual(receivedJson, expectedJson): Boolean {
|
|
35
|
+
let isJsonEqual = true;
|
|
36
|
+
let receivedKeys: string[] = this.getJsonKeys(receivedJson);
|
|
37
|
+
let expectedKeys = this.getJsonKeys(expectedJson);
|
|
38
|
+
let receivedValues = this.getJsonValues(receivedJson);
|
|
39
|
+
let expectedValues = this.getJsonValues(expectedJson);
|
|
40
|
+
let count: number = this.getJsonCount(receivedJson);
|
|
41
|
+
|
|
42
|
+
for (let i: number = 0; i < count; i++) {
|
|
43
|
+
let receivedKey = receivedKeys[i];
|
|
44
|
+
let expectedKey = expectedKeys[i];
|
|
45
|
+
let receivedValue = receivedValues[i];
|
|
46
|
+
let expectedValue = expectedValues[i];
|
|
47
|
+
|
|
48
|
+
let isKeyEmpty: Boolean = receivedKey == (null || '');
|
|
49
|
+
let isKeyEqual: Boolean = receivedKey == expectedKey;
|
|
50
|
+
let isValueEqual: Boolean = isDeepStrictEqual(
|
|
51
|
+
receivedValue,
|
|
52
|
+
expectedValue
|
|
53
|
+
);
|
|
54
|
+
expect.soft(!isKeyEmpty, 'Actual Key received is not null.');
|
|
55
|
+
expect
|
|
56
|
+
.soft(
|
|
57
|
+
isKeyEqual,
|
|
58
|
+
"Actual key received is: '" +
|
|
59
|
+
receivedKey +
|
|
60
|
+
"' and expected key is: '" +
|
|
61
|
+
expectedKey +
|
|
62
|
+
"'."
|
|
63
|
+
)
|
|
64
|
+
.toBeTruthy();
|
|
65
|
+
expect
|
|
66
|
+
.soft(
|
|
67
|
+
isValueEqual,
|
|
68
|
+
"Actual value received for '" +
|
|
69
|
+
expectedKey +
|
|
70
|
+
"' is " +
|
|
71
|
+
JSON.stringify(receivedValue) +
|
|
72
|
+
' and \nExpected value is: ' +
|
|
73
|
+
JSON.stringify(expectedValue) +
|
|
74
|
+
'.'
|
|
75
|
+
)
|
|
76
|
+
.toBeTruthy();
|
|
77
|
+
|
|
78
|
+
if (isKeyEmpty || !isKeyEqual || !isValueEqual) {
|
|
79
|
+
isJsonEqual = false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return isJsonEqual;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//Get Keys from Json Files
|
|
86
|
+
static getJsonKeys(jsonFile) {
|
|
87
|
+
return Object.keys(jsonFile);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
//Get Values From Json Files
|
|
91
|
+
static getJsonValues(jsonFile) {
|
|
92
|
+
return Object.values(jsonFile);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//Get Count of Json items
|
|
96
|
+
static getJsonCount(jsonFile) {
|
|
97
|
+
return Object.keys(jsonFile).length;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { map } from 'lodash';
|
|
2
|
+
import moment, { DurationInputArg1, DurationInputArg2 } from 'moment';
|
|
3
|
+
export class Dateutility {
|
|
4
|
+
static getDateInCustomFormat(date: any, format: string) {
|
|
5
|
+
return moment(date).format(format);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
static getFutureDateInCustomFormat(
|
|
9
|
+
date: any,
|
|
10
|
+
format: string,
|
|
11
|
+
durationType: DurationInputArg2,
|
|
12
|
+
duration: DurationInputArg1
|
|
13
|
+
) {
|
|
14
|
+
return moment(date).add(duration, durationType).format(format);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static getPastDateInCustomFormat(
|
|
18
|
+
date: any,
|
|
19
|
+
format: string,
|
|
20
|
+
durationType: DurationInputArg2,
|
|
21
|
+
duration: DurationInputArg1
|
|
22
|
+
) {
|
|
23
|
+
return moment(date).subtract(duration, durationType).format(format);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static getMinDateFromMultipleDates(datesArrayObject: any) {
|
|
27
|
+
return moment.min(
|
|
28
|
+
map(datesArrayObject, (obj) => moment(obj.date, obj.format))
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static getMaxDateFromMultipleDates(date1: any, date2: any) {
|
|
33
|
+
return moment.max(date1, date2);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static calculateRelativeDate(fromDate: any, format: string) {
|
|
37
|
+
return moment(fromDate, format).fromNow();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import XLSX from 'xlsx';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
// import { PdfReader } from 'pdfreader';
|
|
6
|
+
|
|
7
|
+
export class DocumentUtility {
|
|
8
|
+
static async readData(filePath: string) {
|
|
9
|
+
return XLSX.readFile(filePath, {
|
|
10
|
+
cellDates: true,
|
|
11
|
+
bookVBA: true,
|
|
12
|
+
sheetStubs: true,
|
|
13
|
+
cellNF: true,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static async readDataFromExcelorCSV(filePath: string, sheetname: string) {
|
|
18
|
+
const jsonOpts = {
|
|
19
|
+
raw: false,
|
|
20
|
+
dateNF: `yyyy/mm/dd`, // <--- need dateNF in sheet_to_json options (note the escape chars)
|
|
21
|
+
};
|
|
22
|
+
const workbook = await DocumentUtility.readData(filePath);
|
|
23
|
+
const sheet_name_list = workbook.SheetNames;
|
|
24
|
+
sheetname = sheetname === undefined ? sheet_name_list[0] : sheetname;
|
|
25
|
+
return XLSX.utils.sheet_to_json(
|
|
26
|
+
workbook.Sheets[sheet_name_list[0]],
|
|
27
|
+
jsonOpts
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
// const tempTwoDimentionalArr = new Array(_.keys(excelData[0]).length);
|
|
31
|
+
// for (const i = 0; i < tempTwoDimentionalArr.length; i++) {
|
|
32
|
+
// tempTwoDimentionalArr[i] = new Array();
|
|
33
|
+
// }
|
|
34
|
+
// return _.map(excelData, (obj)=> {
|
|
35
|
+
// return _.reduce(_.keys(excelData[0]), (result, columnName, index) =>{
|
|
36
|
+
// tempTwoDimentionalArr[index].push(obj[columnName])
|
|
37
|
+
// result[columnName] = tempTwoDimentionalArr[index];
|
|
38
|
+
// return result;
|
|
39
|
+
// }, {})
|
|
40
|
+
// })[0];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static async filterData(
|
|
44
|
+
filePath: string,
|
|
45
|
+
sheetName: string,
|
|
46
|
+
filterObject: object
|
|
47
|
+
) {
|
|
48
|
+
let fileData = await DocumentUtility.readData(filePath);
|
|
49
|
+
return _.filter(
|
|
50
|
+
XLSX.utils.sheet_to_json(fileData.Sheets[sheetName]),
|
|
51
|
+
filterObject
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static async updateExcelData(
|
|
56
|
+
filePath: string,
|
|
57
|
+
sheetName: string,
|
|
58
|
+
exportData: Array<object>
|
|
59
|
+
) {
|
|
60
|
+
const workbook = await DocumentUtility.readData(filePath);
|
|
61
|
+
workbook.Sheets[sheetName] = XLSX.utils.json_to_sheet(exportData);
|
|
62
|
+
XLSX.writeFile(workbook, filePath);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static async deleteAllFilesUnderDir(dirPath: string) {
|
|
66
|
+
for (const file of await fs.readdir(dirPath)) {
|
|
67
|
+
await fs.unlink(path.join(dirPath, file));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// static async readPdfFile(filePath: string) {
|
|
72
|
+
// const items = [];
|
|
73
|
+
// return new Promise((resolve, reject) => {
|
|
74
|
+
// new PdfReader().parseFileItems(filePath, (err, item) => {
|
|
75
|
+
// if (err) reject(err);
|
|
76
|
+
// else if (!item) resolve(items);
|
|
77
|
+
// else if (item.text) items.push(item.text);
|
|
78
|
+
// });
|
|
79
|
+
// });
|
|
80
|
+
// }
|
|
81
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import nodemailer from 'nodemailer';
|
|
2
|
+
export class EmailSender {
|
|
3
|
+
static async transporter() {
|
|
4
|
+
return nodemailer.createTransport({
|
|
5
|
+
service: 'Gmail',
|
|
6
|
+
host: 'smtp.gmail.com',
|
|
7
|
+
secure: false,
|
|
8
|
+
auth: {
|
|
9
|
+
user: '***********',
|
|
10
|
+
pass: '***********',
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static async getMailOptions() {
|
|
16
|
+
return {
|
|
17
|
+
from: 'durgaprasad555555@gmail',
|
|
18
|
+
to: 'vemula.d.prasad.tpr@vialto.com',
|
|
19
|
+
subject: 'this testing mail from automation',
|
|
20
|
+
html: `<h2 style="color:#ff6600;">Hello People!,
|
|
21
|
+
Welcome to Vialto!</h2>`,
|
|
22
|
+
attachments: [{ filename: 'test.js', path: './resources/test.js' }],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static async sendMail() {
|
|
27
|
+
const transporter = await this.transporter();
|
|
28
|
+
transporter.sendMail(this.getMailOptions(), (error, info) => {
|
|
29
|
+
if (error) {
|
|
30
|
+
console.log(error);
|
|
31
|
+
} else {
|
|
32
|
+
console.log('email sent: ' + info.message);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|