@anddone/coretestautomation 1.0.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/.github/workflows/npm-release.yml +102 -0
- package/dist/api/base.api.d.ts +32 -0
- package/dist/api/base.api.d.ts.map +1 -0
- package/dist/api/base.api.js +7 -0
- package/dist/api/base.api.js.map +1 -0
- package/dist/api/headers.d.ts +6 -0
- package/dist/api/headers.d.ts.map +1 -0
- package/dist/api/headers.js +23 -0
- package/dist/api/headers.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/pages/basepage.d.ts +6 -0
- package/dist/pages/basepage.d.ts.map +1 -0
- package/dist/pages/basepage.js +10 -0
- package/dist/pages/basepage.js.map +1 -0
- package/dist/testData/api.data.json +6 -0
- package/dist/utils/apiUtils.d.ts +123 -0
- package/dist/utils/apiUtils.d.ts.map +1 -0
- package/dist/utils/apiUtils.js +264 -0
- package/dist/utils/apiUtils.js.map +1 -0
- package/dist/utils/assertionUtils.d.ts +223 -0
- package/dist/utils/assertionUtils.d.ts.map +1 -0
- package/dist/utils/assertionUtils.js +400 -0
- package/dist/utils/assertionUtils.js.map +1 -0
- package/dist/utils/commonUtils.d.ts +590 -0
- package/dist/utils/commonUtils.d.ts.map +1 -0
- package/dist/utils/commonUtils.js +1292 -0
- package/dist/utils/commonUtils.js.map +1 -0
- package/dist/utils/fakerStaticData.d.ts +16 -0
- package/dist/utils/fakerStaticData.d.ts.map +1 -0
- package/dist/utils/fakerStaticData.js +88 -0
- package/dist/utils/fakerStaticData.js.map +1 -0
- package/dist/utils/fileCommonUtils.d.ts +22 -0
- package/dist/utils/fileCommonUtils.d.ts.map +1 -0
- package/dist/utils/fileCommonUtils.js +243 -0
- package/dist/utils/fileCommonUtils.js.map +1 -0
- package/dist/utils/generationUtils.d.ts +424 -0
- package/dist/utils/generationUtils.d.ts.map +1 -0
- package/dist/utils/generationUtils.js +869 -0
- package/dist/utils/generationUtils.js.map +1 -0
- package/dist/utils/pageUtils.d.ts +90 -0
- package/dist/utils/pageUtils.d.ts.map +1 -0
- package/dist/utils/pageUtils.js +214 -0
- package/dist/utils/pageUtils.js.map +1 -0
- package/dist/utils/tableUtils.d.ts +304 -0
- package/dist/utils/tableUtils.d.ts.map +1 -0
- package/dist/utils/tableUtils.js +555 -0
- package/dist/utils/tableUtils.js.map +1 -0
- package/dist/utils/validationUtils.d.ts +80 -0
- package/dist/utils/validationUtils.d.ts.map +1 -0
- package/dist/utils/validationUtils.js +172 -0
- package/dist/utils/validationUtils.js.map +1 -0
- package/package.json +23 -0
- package/playwright.config.ts +79 -0
- package/src/api/base.api.ts +39 -0
- package/src/api/headers.ts +17 -0
- package/src/index.ts +12 -0
- package/src/pages/basepage.ts +11 -0
- package/src/testData/api.data.json +6 -0
- package/src/types/pdf-parse.d.ts +6 -0
- package/src/utils/apiUtils.ts +307 -0
- package/src/utils/assertionUtils.ts +455 -0
- package/src/utils/commonUtils.ts +1544 -0
- package/src/utils/fakerStaticData.ts +91 -0
- package/src/utils/fileCommonUtils.ts +239 -0
- package/src/utils/generationUtils.ts +929 -0
- package/src/utils/pageUtils.ts +224 -0
- package/src/utils/tableUtils.ts +715 -0
- package/src/utils/validationUtils.ts +179 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidationUtils = void 0;
|
|
4
|
+
const date_fns_1 = require("date-fns");
|
|
5
|
+
class ValidationUtils {
|
|
6
|
+
/**
|
|
7
|
+
* Checks whether a Date object is valid.
|
|
8
|
+
*
|
|
9
|
+
* @param date Date object
|
|
10
|
+
* @returns true if valid Date, false otherwise
|
|
11
|
+
*/
|
|
12
|
+
static isValidDate(date) {
|
|
13
|
+
try {
|
|
14
|
+
return date instanceof Date && (0, date_fns_1.isValid)(date);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Checks whether two dates fall on the same calendar day.
|
|
22
|
+
*
|
|
23
|
+
* @param date1 First date
|
|
24
|
+
* @param date2 Second date
|
|
25
|
+
* @returns True if date1 is before date2
|
|
26
|
+
*/
|
|
27
|
+
static isBefore(date1, date2) {
|
|
28
|
+
try {
|
|
29
|
+
return this.isValidDate(date1) && this.isValidDate(date2) && date1.getTime() < date2.getTime();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Checks whether two dates fall on the same calendar day.
|
|
37
|
+
*
|
|
38
|
+
* @param date1 First date
|
|
39
|
+
* @param date2 Second date
|
|
40
|
+
* @returns True if date1 is after date2
|
|
41
|
+
*/
|
|
42
|
+
static isAfter(date1, date2) {
|
|
43
|
+
try {
|
|
44
|
+
return this.isValidDate(date1) && this.isValidDate(date2) && date1.getTime() > date2.getTime();
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Checks whether two dates fall on the same calendar day.
|
|
52
|
+
*
|
|
53
|
+
* @param date1 First date
|
|
54
|
+
* @param date2 Second date
|
|
55
|
+
* @returns True if both dates are on the same day
|
|
56
|
+
*/
|
|
57
|
+
static isSameDay(date1, date2) {
|
|
58
|
+
try {
|
|
59
|
+
if (!this.isValidDate(date1) || !this.isValidDate(date2))
|
|
60
|
+
return false;
|
|
61
|
+
return (date1.getFullYear() === date2.getFullYear() &&
|
|
62
|
+
date1.getMonth() === date2.getMonth() &&
|
|
63
|
+
date1.getDate() === date2.getDate());
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Checks whether a list of dates is in ascending order (oldest → newest).
|
|
71
|
+
*
|
|
72
|
+
* @param dates Array of Date objects
|
|
73
|
+
* @returns true if dates are in ascending order
|
|
74
|
+
*/
|
|
75
|
+
static isAscendingDateList(dates) {
|
|
76
|
+
try {
|
|
77
|
+
if (!Array.isArray(dates) || dates.length < 2)
|
|
78
|
+
return true;
|
|
79
|
+
for (let i = 1; i < dates.length; i++) {
|
|
80
|
+
if (!this.isAfter(dates[i], dates[i - 1]) &&
|
|
81
|
+
dates[i].getTime() !== dates[i - 1].getTime()) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Checks whether a list of dates is in descending order (newest → oldest).
|
|
93
|
+
*
|
|
94
|
+
* @param dates Array of Date objects
|
|
95
|
+
* @returns true if dates are in descending order
|
|
96
|
+
*/
|
|
97
|
+
static isDescendingDateList(dates) {
|
|
98
|
+
try {
|
|
99
|
+
if (!Array.isArray(dates) || dates.length < 2)
|
|
100
|
+
return true;
|
|
101
|
+
for (let i = 1; i < dates.length; i++) {
|
|
102
|
+
if (!this.isBefore(dates[i], dates[i - 1]) &&
|
|
103
|
+
dates[i].getTime() !== dates[i - 1].getTime()) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Checks whether a date string strictly matches the given date format.
|
|
115
|
+
*
|
|
116
|
+
* @param dateStr input date string
|
|
117
|
+
* @param formatStr expected date format
|
|
118
|
+
* @returns true if date matches the format exactly, false otherwise
|
|
119
|
+
*
|
|
120
|
+
* Example:
|
|
121
|
+
* doesDateMatchFormat("02/10/2003", "dd/MM/yyyy") → true
|
|
122
|
+
* doesDateMatchFormat("2/10/2003", "dd/MM/yyyy") → false
|
|
123
|
+
*/
|
|
124
|
+
static isDateMatchFormat(dateStr, formatStr) {
|
|
125
|
+
try {
|
|
126
|
+
if (!dateStr || !formatStr)
|
|
127
|
+
return false;
|
|
128
|
+
const parsedDate = (0, date_fns_1.parse)(dateStr, formatStr, new Date());
|
|
129
|
+
if (!this.isValidDate(parsedDate))
|
|
130
|
+
return false;
|
|
131
|
+
const reformatted = (0, date_fns_1.format)(parsedDate, formatStr);
|
|
132
|
+
return reformatted === dateStr;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Checks whether a string matches a given regular expression.
|
|
140
|
+
*
|
|
141
|
+
* @param value Input string to test
|
|
142
|
+
* @param pattern Regular expression pattern
|
|
143
|
+
* @returns true if pattern matches, otherwise false
|
|
144
|
+
*
|
|
145
|
+
* Example:
|
|
146
|
+
* matchRegex("test@example.com", /^[^\s@]+@[^\s@]+\.[^\s@]+$/) → true
|
|
147
|
+
*/
|
|
148
|
+
static isMatchedRegex(value, pattern) {
|
|
149
|
+
try {
|
|
150
|
+
if (!value || !pattern)
|
|
151
|
+
return false;
|
|
152
|
+
return pattern.test(value);
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Validates whether the actual transaction/payment ID matches
|
|
160
|
+
* the expected partially visible and hidden (masked) pattern.
|
|
161
|
+
* @since 27-01-2026
|
|
162
|
+
* @param actualId String (Full transaction/payment ID)
|
|
163
|
+
* @param expectedId String (Expected masked transaction/payment ID)
|
|
164
|
+
* @returns true if the masked actual ID matches the expected ID, otherwise false
|
|
165
|
+
*/
|
|
166
|
+
static isTransactionIdMatchingPartialVisibleHiddenPattern(actualId, expectedId) {
|
|
167
|
+
const maskedActualId = `${actualId.slice(0, 6)}...${actualId.slice(-6)}`;
|
|
168
|
+
return expectedId === maskedActualId;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.ValidationUtils = ValidationUtils;
|
|
172
|
+
//# sourceMappingURL=validationUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validationUtils.js","sourceRoot":"","sources":["../../src/utils/validationUtils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@anddone/coretestautomation",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"clean": "rimraf dist",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"prepublishOnly": "npm run build"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@playwright/test": "^1.58.0",
|
|
13
|
+
"@types/node": "^25.1.0",
|
|
14
|
+
"@types/xml2js": "^0.4.14"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"date-fns": "^4.1.0",
|
|
18
|
+
"date-fns-tz": "^3.2.0",
|
|
19
|
+
"pdf-parse": "^1.1.1",
|
|
20
|
+
"xlsx": "^0.18.5",
|
|
21
|
+
"xml2js": "^0.6.2"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Read environment variables from file.
|
|
5
|
+
* https://github.com/motdotla/dotenv
|
|
6
|
+
*/
|
|
7
|
+
// import dotenv from 'dotenv';
|
|
8
|
+
// import path from 'path';
|
|
9
|
+
// dotenv.config({ path: path.resolve(__dirname, '.env') });
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* See https://playwright.dev/docs/test-configuration.
|
|
13
|
+
*/
|
|
14
|
+
export default defineConfig({
|
|
15
|
+
testDir: './tests',
|
|
16
|
+
/* Run tests in files in parallel */
|
|
17
|
+
fullyParallel: true,
|
|
18
|
+
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
|
19
|
+
forbidOnly: !!process.env.CI,
|
|
20
|
+
/* Retry on CI only */
|
|
21
|
+
retries: process.env.CI ? 2 : 0,
|
|
22
|
+
/* Opt out of parallel tests on CI. */
|
|
23
|
+
workers: process.env.CI ? 1 : undefined,
|
|
24
|
+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
|
25
|
+
reporter: 'html',
|
|
26
|
+
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
|
27
|
+
use: {
|
|
28
|
+
/* Base URL to use in actions like `await page.goto('')`. */
|
|
29
|
+
// baseURL: 'http://localhost:3000',
|
|
30
|
+
|
|
31
|
+
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
|
32
|
+
trace: 'on-first-retry',
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/* Configure projects for major browsers */
|
|
36
|
+
projects: [
|
|
37
|
+
{
|
|
38
|
+
name: 'chromium',
|
|
39
|
+
use: { ...devices['Desktop Chrome'] },
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
{
|
|
43
|
+
name: 'firefox',
|
|
44
|
+
use: { ...devices['Desktop Firefox'] },
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
{
|
|
48
|
+
name: 'webkit',
|
|
49
|
+
use: { ...devices['Desktop Safari'] },
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
/* Test against mobile viewports. */
|
|
53
|
+
// {
|
|
54
|
+
// name: 'Mobile Chrome',
|
|
55
|
+
// use: { ...devices['Pixel 5'] },
|
|
56
|
+
// },
|
|
57
|
+
// {
|
|
58
|
+
// name: 'Mobile Safari',
|
|
59
|
+
// use: { ...devices['iPhone 12'] },
|
|
60
|
+
// },
|
|
61
|
+
|
|
62
|
+
/* Test against branded browsers. */
|
|
63
|
+
// {
|
|
64
|
+
// name: 'Microsoft Edge',
|
|
65
|
+
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
|
66
|
+
// },
|
|
67
|
+
// {
|
|
68
|
+
// name: 'Google Chrome',
|
|
69
|
+
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
|
70
|
+
// },
|
|
71
|
+
],
|
|
72
|
+
|
|
73
|
+
/* Run your local dev server before starting the tests */
|
|
74
|
+
// webServer: {
|
|
75
|
+
// command: 'npm run start',
|
|
76
|
+
// url: 'http://localhost:3000',
|
|
77
|
+
// reuseExistingServer: !process.env.CI,
|
|
78
|
+
// },
|
|
79
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
|
|
2
|
+
export type Header = {
|
|
3
|
+
origin?: string;
|
|
4
|
+
contentType?: string;
|
|
5
|
+
authorization?: string;
|
|
6
|
+
appKey?: string;
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
xVersion?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type Customer = {
|
|
12
|
+
firstName?: string;
|
|
13
|
+
lastName?: string;
|
|
14
|
+
phone?: string;
|
|
15
|
+
email?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type Reference = {
|
|
19
|
+
referenceType?: string;
|
|
20
|
+
referenceKey?: string;
|
|
21
|
+
referenceNumber?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type Split = {
|
|
25
|
+
virtualAccount?: string;
|
|
26
|
+
amount?: number | string;
|
|
27
|
+
reference?: string;
|
|
28
|
+
chargeIndicator?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type Login = {
|
|
32
|
+
userName?: string;
|
|
33
|
+
password?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class BaseAPI {
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Header } from "./base.api";
|
|
2
|
+
|
|
3
|
+
export class Headers {
|
|
4
|
+
static headers: Record<string, string>;
|
|
5
|
+
|
|
6
|
+
static getHeaders(options: Header = {}) {
|
|
7
|
+
this.headers = {};
|
|
8
|
+
if (options.origin) this.headers["Origin"] = options.origin;
|
|
9
|
+
if (options.contentType) this.headers["Content-Type"] = options.contentType;
|
|
10
|
+
if (options.authorization)
|
|
11
|
+
this.headers["Authorization"] = "Bearer " + options.authorization;
|
|
12
|
+
if (options.xVersion) this.headers["x-version"] = options.xVersion;
|
|
13
|
+
if (options.apiKey) this.headers["x-api-key"] = options.apiKey;
|
|
14
|
+
if (options.appKey) this.headers["x-app-key"] = options.appKey;
|
|
15
|
+
return this.headers;
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "./pages/basepage";
|
|
2
|
+
export * from "./utils/apiUtils";
|
|
3
|
+
export * from "./utils/assertionUtils";
|
|
4
|
+
export * from "./utils/commonUtils";
|
|
5
|
+
export * from "./utils/fakerStaticData";
|
|
6
|
+
export * from "./utils/fileCommonUtils";
|
|
7
|
+
export * from "./utils/generationUtils";
|
|
8
|
+
export * from "./utils/pageUtils";
|
|
9
|
+
export * from "./utils/tableUtils";
|
|
10
|
+
export * from "./utils/validationUtils";
|
|
11
|
+
export * from "./api/base.api";
|
|
12
|
+
export * from "./api/headers";
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { APIRequestContext, APIResponse } from "@playwright/test";
|
|
2
|
+
import apiData from "../testData/api.data.json";
|
|
3
|
+
|
|
4
|
+
type ApiName = keyof typeof apiData;
|
|
5
|
+
|
|
6
|
+
type RequestOptions = {
|
|
7
|
+
body?: unknown;
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
queryParams?: Record<string, string | number | boolean>;
|
|
10
|
+
pathParams?: Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export class EmptyApiResponse {
|
|
14
|
+
status() {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
ok() {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
url() {
|
|
21
|
+
return "";
|
|
22
|
+
}
|
|
23
|
+
async json() {
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
async text() {
|
|
27
|
+
return "";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class ApiUtils {
|
|
32
|
+
private static apiLogs = false;
|
|
33
|
+
|
|
34
|
+
private static request: APIRequestContext;
|
|
35
|
+
private static response: APIResponse;
|
|
36
|
+
|
|
37
|
+
private static apiMethod: string;
|
|
38
|
+
private static apiPath: string;
|
|
39
|
+
|
|
40
|
+
private static responseCode: number;
|
|
41
|
+
private static responseBody: any;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* This is private method to print json value in pretty format.
|
|
45
|
+
* @param obj
|
|
46
|
+
* @returns
|
|
47
|
+
*/
|
|
48
|
+
private static pretty(obj: unknown) {
|
|
49
|
+
try {
|
|
50
|
+
return JSON.stringify(obj, null, 2);
|
|
51
|
+
} catch {
|
|
52
|
+
return String(obj);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* This method to set APIRequestContext object.
|
|
58
|
+
* @param request APIRequestContext
|
|
59
|
+
*/
|
|
60
|
+
static setRequest(request: APIRequestContext) {
|
|
61
|
+
this.request = request;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* This method will returns APIRequestContext object.
|
|
66
|
+
* @returns APIRequestContext
|
|
67
|
+
*/
|
|
68
|
+
static getRequest() {
|
|
69
|
+
return this.request;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* This method set apiMethod and apiPath using apiData object of the json file.
|
|
74
|
+
* @param apiName ApiName
|
|
75
|
+
*/
|
|
76
|
+
static setApiData(apiName: ApiName) {
|
|
77
|
+
this.apiMethod = apiData[apiName].method;
|
|
78
|
+
this.apiPath = apiData[apiName].path;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* This method is to get api method.
|
|
83
|
+
* @returns string
|
|
84
|
+
*/
|
|
85
|
+
static geApiMethod() {
|
|
86
|
+
return this.apiMethod;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* This method is get api path.
|
|
91
|
+
* @returns string
|
|
92
|
+
*/
|
|
93
|
+
static getApiPath() {
|
|
94
|
+
return this.apiPath;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private static buildPath(
|
|
98
|
+
apiPath: string,
|
|
99
|
+
pathParams?: Record<string, string>,
|
|
100
|
+
): string {
|
|
101
|
+
if (!pathParams) return apiPath;
|
|
102
|
+
let finalPath = apiPath;
|
|
103
|
+
for (const [key, value] of Object.entries(pathParams)) {
|
|
104
|
+
finalPath = finalPath.replace(
|
|
105
|
+
new RegExp(`{${key}}`, "g"),
|
|
106
|
+
encodeURIComponent(String(value)),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return finalPath;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* This method to log request details in console if apiLogs flag is true.
|
|
114
|
+
* @param method string | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
|
|
115
|
+
* @param url string
|
|
116
|
+
* @param options RequestOptions
|
|
117
|
+
*/
|
|
118
|
+
static logRequest(
|
|
119
|
+
method: string | "GET" | "POST" | "PUT" | "DELETE" | "PATCH",
|
|
120
|
+
url: string,
|
|
121
|
+
options?: RequestOptions,
|
|
122
|
+
) {
|
|
123
|
+
if (this.apiLogs) {
|
|
124
|
+
console.log("Request:");
|
|
125
|
+
console.log(method, url);
|
|
126
|
+
if (options?.headers)
|
|
127
|
+
console.log("Headers:", this.pretty(options.headers));
|
|
128
|
+
if (options?.body) console.log("Body:", this.pretty(options.body));
|
|
129
|
+
if (options?.queryParams)
|
|
130
|
+
console.log("Query Params:", this.pretty(options.queryParams));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* This method is set APIResponse object along with responseCode and responseBody.
|
|
136
|
+
* Also log response details in console if apiLogs flag is true.
|
|
137
|
+
* @param response APIResponse
|
|
138
|
+
*/
|
|
139
|
+
static async setResponse(response: APIResponse) {
|
|
140
|
+
this.response = response;
|
|
141
|
+
try {
|
|
142
|
+
this.responseCode = this.response?.status?.() ?? 0;
|
|
143
|
+
} catch (e) {
|
|
144
|
+
this.responseCode = 0;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
this.responseBody = await response.json();
|
|
148
|
+
} catch (e) {
|
|
149
|
+
this.responseBody = {};
|
|
150
|
+
}
|
|
151
|
+
this.logResponse();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* This method is get APIResponse object.
|
|
156
|
+
* @returns APIResponse
|
|
157
|
+
*/
|
|
158
|
+
static getResponse() {
|
|
159
|
+
return this.response;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* This method is get response code.
|
|
164
|
+
* @returns number
|
|
165
|
+
*/
|
|
166
|
+
static getResponseCode(): number {
|
|
167
|
+
return this.responseCode;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* This method is get response body.
|
|
172
|
+
* @returns T = unknown
|
|
173
|
+
*/
|
|
174
|
+
static getResponseBody<T = unknown>(): T {
|
|
175
|
+
return this.responseBody;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* This method is log response details in console if apiLogs flag is true.
|
|
180
|
+
*/
|
|
181
|
+
static logResponse() {
|
|
182
|
+
if (this.apiLogs) {
|
|
183
|
+
console.log("Response:");
|
|
184
|
+
console.log("Status Code:", this.getResponseCode());
|
|
185
|
+
console.log("Body:", this.pretty(this.getResponseBody()));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* This method is to send respuest as per passed details and return response.
|
|
191
|
+
* @param method string | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
|
|
192
|
+
* @param url string - passed Base Url and endpoint together, example: {BaseUrl}+{ApiPath}
|
|
193
|
+
* @param options RequestOptions - this is optional.
|
|
194
|
+
* @returns @link APIResponse
|
|
195
|
+
*
|
|
196
|
+
* Examples:
|
|
197
|
+
* const response = sendRequest('POST', {BaseUrl}+{ApiPath}, {headers: {...headers}, body: {...payload}});
|
|
198
|
+
*/
|
|
199
|
+
static async sendRequest(
|
|
200
|
+
method: string | "GET" | "POST" | "PUT" | "DELETE" | "PATCH",
|
|
201
|
+
url: string,
|
|
202
|
+
options?: RequestOptions,
|
|
203
|
+
) {
|
|
204
|
+
url = this.buildPath(url, options?.pathParams);
|
|
205
|
+
this.logRequest(method, url, options);
|
|
206
|
+
const reqOptions: {
|
|
207
|
+
headers?: Record<string, string>;
|
|
208
|
+
params?: Record<string, string | number | boolean>;
|
|
209
|
+
data?: unknown;
|
|
210
|
+
} = {};
|
|
211
|
+
if (options?.headers) reqOptions.headers = options.headers;
|
|
212
|
+
if (options?.queryParams) reqOptions.params = options.queryParams;
|
|
213
|
+
if (options?.body) reqOptions.data = options.body;
|
|
214
|
+
try {
|
|
215
|
+
const response = await this.getRequest().fetch(url, {
|
|
216
|
+
method,
|
|
217
|
+
...reqOptions,
|
|
218
|
+
});
|
|
219
|
+
return response;
|
|
220
|
+
} catch (error) {
|
|
221
|
+
const empty = new EmptyApiResponse() as any;
|
|
222
|
+
await this.setResponse(empty);
|
|
223
|
+
return empty;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* This method is get response object value as per passed path.
|
|
229
|
+
* Also if object value not found then you set return some defaultValue which is optional.
|
|
230
|
+
* @param path string - example 'token', 'intent.paymentTypes', 'customers[0].firstName'
|
|
231
|
+
* @param defaultValue T = any
|
|
232
|
+
* @returns T = any
|
|
233
|
+
*/
|
|
234
|
+
static async getResponseValue<T = any>(
|
|
235
|
+
path: string,
|
|
236
|
+
defaultValue?: T,
|
|
237
|
+
): Promise<T> {
|
|
238
|
+
try {
|
|
239
|
+
const body = (await this.getResponseBody()) as any;
|
|
240
|
+
if (!body || !path) {
|
|
241
|
+
return defaultValue !== undefined ? defaultValue : ("" as any);
|
|
242
|
+
}
|
|
243
|
+
const result = path
|
|
244
|
+
.replace(/\[(\d+)\]/g, ".$1")
|
|
245
|
+
.split(".")
|
|
246
|
+
.reduce((obj, key) => obj?.[key], body);
|
|
247
|
+
if (result === undefined || result === null) {
|
|
248
|
+
return defaultValue !== undefined ? defaultValue : ("" as any);
|
|
249
|
+
}
|
|
250
|
+
return result;
|
|
251
|
+
} catch {
|
|
252
|
+
return defaultValue !== undefined ? defaultValue : ("" as any);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* This method is get response object value as array.
|
|
258
|
+
* @param path string - example 'customers'
|
|
259
|
+
* @returns T = any []
|
|
260
|
+
*/
|
|
261
|
+
static async getResponseArray<T = any>(path: string): Promise<T[]> {
|
|
262
|
+
const value = await this.getResponseValue(path, []);
|
|
263
|
+
return Array.isArray(value) ? value : [];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Finds an object inside an array and returns its id where multiple fields match
|
|
268
|
+
* @param arrayPath Path to array. Example: "data"
|
|
269
|
+
* @param match Object with fields to match. Example: { allyName: "Zbook1201", status: "ACTIVE" }
|
|
270
|
+
* @param objectName Object name of which value return . "id"
|
|
271
|
+
*/
|
|
272
|
+
static async getResponseValueFromArray(
|
|
273
|
+
arrayPath: string,
|
|
274
|
+
objectName: string,
|
|
275
|
+
match: Record<string, any>,
|
|
276
|
+
): Promise<string> {
|
|
277
|
+
try {
|
|
278
|
+
if (!match || typeof match !== "object") {
|
|
279
|
+
return "";
|
|
280
|
+
}
|
|
281
|
+
let arr: any[];
|
|
282
|
+
if (!arrayPath) {
|
|
283
|
+
const body = await this.getResponseBody();
|
|
284
|
+
arr = Array.isArray(body) ? body : [];
|
|
285
|
+
} else {
|
|
286
|
+
arr = await this.getResponseArray<any>(arrayPath);
|
|
287
|
+
}
|
|
288
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
289
|
+
return "";
|
|
290
|
+
}
|
|
291
|
+
const found = arr.find((item) => {
|
|
292
|
+
if (!item || typeof item !== "object") return false;
|
|
293
|
+
return Object.entries(match).every(
|
|
294
|
+
([key, value]) => item?.[key] === value,
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
if (!found || typeof found !== "object") {
|
|
298
|
+
return "";
|
|
299
|
+
}
|
|
300
|
+
const result = found?.[objectName];
|
|
301
|
+
return result !== undefined && result !== null ? String(result) : "";
|
|
302
|
+
} catch (error) {
|
|
303
|
+
// Optional: console.warn("⚠️ getResponseValueFromArray failed:", error);
|
|
304
|
+
return "";
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|