@qate/cli 1.0.0 → 1.1.0
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/README.md +449 -449
- package/dist/AuthFlowExecutor.d.ts +87 -0
- package/dist/AuthFlowExecutor.d.ts.map +1 -0
- package/dist/AuthFlowExecutor.js +351 -0
- package/dist/AuthFlowExecutor.js.map +1 -0
- package/dist/AxiosGenerator.js +28 -28
- package/dist/JunitXmlGenerator.d.ts +12 -0
- package/dist/JunitXmlGenerator.d.ts.map +1 -0
- package/dist/JunitXmlGenerator.js +114 -0
- package/dist/JunitXmlGenerator.js.map +1 -0
- package/dist/PlaywrightGenerator.d.ts +1 -1
- package/dist/PlaywrightGenerator.d.ts.map +1 -1
- package/dist/PlaywrightGenerator.js +796 -758
- package/dist/PlaywrightGenerator.js.map +1 -1
- package/dist/RestApiExecutor.d.ts +3 -4
- package/dist/RestApiExecutor.d.ts.map +1 -1
- package/dist/RestApiExecutor.js +63 -3
- package/dist/RestApiExecutor.js.map +1 -1
- package/dist/cli.js +536 -148
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +78 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +47 -6
- package/dist/client.js.map +1 -1
- package/package.json +71 -71
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Flow Executor for CLI
|
|
3
|
+
* Ports auth flow execution from electron-test-agent/src/tools/RestApiTools.js
|
|
4
|
+
* Executes authentication flows locally to obtain auth headers/params for API tests
|
|
5
|
+
*/
|
|
6
|
+
export interface AuthVariable {
|
|
7
|
+
name: string;
|
|
8
|
+
source: string;
|
|
9
|
+
type: 'extract' | 'literal' | 'env';
|
|
10
|
+
}
|
|
11
|
+
export interface AuthTransform {
|
|
12
|
+
name: string;
|
|
13
|
+
operation: string;
|
|
14
|
+
input: any;
|
|
15
|
+
parameters?: any;
|
|
16
|
+
}
|
|
17
|
+
export interface AuthExtraction {
|
|
18
|
+
name: string;
|
|
19
|
+
path: string;
|
|
20
|
+
defaultValue?: any;
|
|
21
|
+
}
|
|
22
|
+
export interface AuthCondition {
|
|
23
|
+
field: string;
|
|
24
|
+
operator: 'equals' | 'not_equals' | 'contains' | 'exists' | 'greater_than' | 'less_than';
|
|
25
|
+
value: any;
|
|
26
|
+
onTrue?: string;
|
|
27
|
+
onFalse?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface AuthHttpRequest {
|
|
30
|
+
url: string;
|
|
31
|
+
method: string;
|
|
32
|
+
headers?: Record<string, string>;
|
|
33
|
+
body?: any;
|
|
34
|
+
bodyType?: 'json' | 'x-www-form-urlencoded';
|
|
35
|
+
timeout?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface AuthStep {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
type: 'http_request' | 'load_vars' | 'transform' | 'condition';
|
|
41
|
+
description?: string;
|
|
42
|
+
request?: AuthHttpRequest;
|
|
43
|
+
load?: AuthVariable[];
|
|
44
|
+
transform?: AuthTransform[];
|
|
45
|
+
condition?: AuthCondition;
|
|
46
|
+
extract?: AuthExtraction[];
|
|
47
|
+
onError?: {
|
|
48
|
+
action: 'fail' | 'continue' | 'retry';
|
|
49
|
+
retryCount?: number;
|
|
50
|
+
continueStep?: string;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export interface AuthOutput {
|
|
54
|
+
name: string;
|
|
55
|
+
value: string;
|
|
56
|
+
type: 'header' | 'query_param' | 'body_param';
|
|
57
|
+
}
|
|
58
|
+
export interface AuthDefinition {
|
|
59
|
+
id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
roleName?: string;
|
|
62
|
+
authType?: string;
|
|
63
|
+
steps: AuthStep[];
|
|
64
|
+
outputs: AuthOutput[];
|
|
65
|
+
settings?: {
|
|
66
|
+
timeout?: number;
|
|
67
|
+
retryOnFailure?: boolean;
|
|
68
|
+
maxRetries?: number;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export interface AuthData {
|
|
72
|
+
headers: Record<string, string>;
|
|
73
|
+
queryParams: Record<string, string>;
|
|
74
|
+
bodyParams: Record<string, string>;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Execute authentication flow and return auth data
|
|
78
|
+
*/
|
|
79
|
+
export declare function executeAuthFlow(authDefinition: AuthDefinition): Promise<AuthData>;
|
|
80
|
+
/**
|
|
81
|
+
* Apply auth data to request config (headers, query params)
|
|
82
|
+
*/
|
|
83
|
+
export declare function applyAuthToRequest(requestConfig: {
|
|
84
|
+
url: string;
|
|
85
|
+
headers?: Record<string, string>;
|
|
86
|
+
}, authData: AuthData): void;
|
|
87
|
+
//# sourceMappingURL=AuthFlowExecutor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthFlowExecutor.d.ts","sourceRoot":"","sources":["../src/AuthFlowExecutor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,GAAG,CAAC;IACX,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,cAAc,GAAG,WAAW,CAAC;IACzF,KAAK,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,GAAG,uBAAuB,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;QACtC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC;CAC/C;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAeD;;GAEG;AACH,wBAAsB,eAAe,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8CvF;AAqSD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAChE,QAAQ,EAAE,QAAQ,GACjB,IAAI,CAiBN"}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Auth Flow Executor for CLI
|
|
4
|
+
* Ports auth flow execution from electron-test-agent/src/tools/RestApiTools.js
|
|
5
|
+
* Executes authentication flows locally to obtain auth headers/params for API tests
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.executeAuthFlow = executeAuthFlow;
|
|
12
|
+
exports.applyAuthToRequest = applyAuthToRequest;
|
|
13
|
+
const axios_1 = __importDefault(require("axios"));
|
|
14
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
15
|
+
// ============ Cache ============
|
|
16
|
+
const authCache = new Map();
|
|
17
|
+
const AUTH_CACHE_DURATION_MS = 5 * 60 * 1000; // 5 minutes
|
|
18
|
+
// ============ Main Functions ============
|
|
19
|
+
/**
|
|
20
|
+
* Execute authentication flow and return auth data
|
|
21
|
+
*/
|
|
22
|
+
async function executeAuthFlow(authDefinition) {
|
|
23
|
+
if (!authDefinition || !authDefinition.steps || authDefinition.steps.length === 0) {
|
|
24
|
+
return { headers: {}, queryParams: {}, bodyParams: {} };
|
|
25
|
+
}
|
|
26
|
+
// Check cache
|
|
27
|
+
const cacheKeyContent = JSON.stringify({
|
|
28
|
+
id: authDefinition.id,
|
|
29
|
+
steps: authDefinition.steps,
|
|
30
|
+
outputs: authDefinition.outputs
|
|
31
|
+
});
|
|
32
|
+
const cacheKey = crypto_1.default.createHash('md5').update(cacheKeyContent).digest('hex');
|
|
33
|
+
const cached = authCache.get(cacheKey);
|
|
34
|
+
if (cached && Date.now() < cached.expiry) {
|
|
35
|
+
return cached.authData;
|
|
36
|
+
}
|
|
37
|
+
const context = {
|
|
38
|
+
env: process.env,
|
|
39
|
+
steps: {},
|
|
40
|
+
variables: {}
|
|
41
|
+
};
|
|
42
|
+
// Execute steps sequentially
|
|
43
|
+
for (const step of authDefinition.steps) {
|
|
44
|
+
try {
|
|
45
|
+
const stepResult = await executeAuthStep(step, context);
|
|
46
|
+
context.steps[step.id] = stepResult;
|
|
47
|
+
}
|
|
48
|
+
catch (stepError) {
|
|
49
|
+
if (step.onError?.action === 'continue') {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
throw stepError;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Generate outputs
|
|
56
|
+
const authData = generateAuthData(authDefinition.outputs || [], context);
|
|
57
|
+
// Cache the result
|
|
58
|
+
authCache.set(cacheKey, {
|
|
59
|
+
authData,
|
|
60
|
+
expiry: Date.now() + AUTH_CACHE_DURATION_MS
|
|
61
|
+
});
|
|
62
|
+
return authData;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Execute a single auth step
|
|
66
|
+
*/
|
|
67
|
+
async function executeAuthStep(step, context) {
|
|
68
|
+
switch (step.type) {
|
|
69
|
+
case 'http_request':
|
|
70
|
+
return await executeHttpRequestStep(step, context);
|
|
71
|
+
case 'load_vars':
|
|
72
|
+
return executeLoadVarsStep(step, context);
|
|
73
|
+
case 'transform':
|
|
74
|
+
return executeTransformStep(step, context);
|
|
75
|
+
case 'condition':
|
|
76
|
+
return executeConditionStep(step, context);
|
|
77
|
+
default:
|
|
78
|
+
throw new Error(`Unknown step type: ${step.type}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Execute HTTP request auth step
|
|
83
|
+
*/
|
|
84
|
+
async function executeHttpRequestStep(step, context) {
|
|
85
|
+
const request = step.request;
|
|
86
|
+
const url = resolveTemplate(request.url, context);
|
|
87
|
+
const headers = {};
|
|
88
|
+
for (const [key, value] of Object.entries(request.headers || {})) {
|
|
89
|
+
headers[key] = resolveTemplate(value, context);
|
|
90
|
+
}
|
|
91
|
+
let body = null;
|
|
92
|
+
if (request.body && ['POST', 'PUT', 'PATCH'].includes(request.method)) {
|
|
93
|
+
// Check if form-urlencoded
|
|
94
|
+
const isFormUrlEncoded = request.bodyType === 'x-www-form-urlencoded' ||
|
|
95
|
+
(headers['Content-Type'] || '').includes('x-www-form-urlencoded');
|
|
96
|
+
if (isFormUrlEncoded) {
|
|
97
|
+
if (Array.isArray(request.body)) {
|
|
98
|
+
// Key-value pair format: [{key, value}]
|
|
99
|
+
const params = new URLSearchParams();
|
|
100
|
+
for (const pair of request.body) {
|
|
101
|
+
params.append(resolveTemplate(pair.key, context), resolveTemplate(pair.value, context));
|
|
102
|
+
}
|
|
103
|
+
body = params.toString();
|
|
104
|
+
}
|
|
105
|
+
else if (typeof request.body === 'object') {
|
|
106
|
+
// Plain object format (backward compat)
|
|
107
|
+
const resolved = resolveTemplateObject(request.body, context);
|
|
108
|
+
const params = new URLSearchParams();
|
|
109
|
+
for (const [key, value] of Object.entries(resolved)) {
|
|
110
|
+
params.append(key, String(value));
|
|
111
|
+
}
|
|
112
|
+
body = params.toString();
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
body = resolveTemplate(request.body, context);
|
|
116
|
+
}
|
|
117
|
+
if (!headers['Content-Type']) {
|
|
118
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else if (typeof request.body === 'object') {
|
|
122
|
+
body = resolveTemplateObject(request.body, context);
|
|
123
|
+
if (!headers['Content-Type']) {
|
|
124
|
+
headers['Content-Type'] = 'application/json';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
body = resolveTemplate(request.body, context);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const response = await (0, axios_1.default)({
|
|
132
|
+
method: request.method,
|
|
133
|
+
url,
|
|
134
|
+
headers,
|
|
135
|
+
data: body,
|
|
136
|
+
timeout: request.timeout || 30000,
|
|
137
|
+
validateStatus: () => true
|
|
138
|
+
});
|
|
139
|
+
if (response.status >= 400) {
|
|
140
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText || 'Error'}`);
|
|
141
|
+
}
|
|
142
|
+
const responseData = response.data;
|
|
143
|
+
// Extract data from response
|
|
144
|
+
const extractedData = {};
|
|
145
|
+
if (step.extract) {
|
|
146
|
+
for (const extraction of step.extract) {
|
|
147
|
+
try {
|
|
148
|
+
const value = extractJsonPath(responseData, extraction.path) || extraction.defaultValue;
|
|
149
|
+
extractedData[extraction.name] = value;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
extractedData[extraction.name] = extraction.defaultValue;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
response: responseData,
|
|
158
|
+
...extractedData
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Execute load variables step
|
|
163
|
+
*/
|
|
164
|
+
function executeLoadVarsStep(step, context) {
|
|
165
|
+
const loadedVars = {};
|
|
166
|
+
for (const variable of step.load || []) {
|
|
167
|
+
let value;
|
|
168
|
+
switch (variable.type) {
|
|
169
|
+
case 'env':
|
|
170
|
+
value = process.env[variable.source];
|
|
171
|
+
break;
|
|
172
|
+
case 'literal':
|
|
173
|
+
value = variable.source;
|
|
174
|
+
break;
|
|
175
|
+
case 'extract':
|
|
176
|
+
value = extractJsonPath(context, variable.source);
|
|
177
|
+
break;
|
|
178
|
+
default:
|
|
179
|
+
value = variable.source;
|
|
180
|
+
}
|
|
181
|
+
loadedVars[variable.name] = value;
|
|
182
|
+
}
|
|
183
|
+
// Apply transformations
|
|
184
|
+
if (step.transform) {
|
|
185
|
+
for (const transform of step.transform) {
|
|
186
|
+
const input = resolveTemplate(transform.input, { ...context, ...loadedVars });
|
|
187
|
+
const transformedValue = applyTransformation(transform.operation, input, transform.parameters);
|
|
188
|
+
loadedVars[transform.name] = transformedValue;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return loadedVars;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Execute transform step
|
|
195
|
+
*/
|
|
196
|
+
function executeTransformStep(step, context) {
|
|
197
|
+
const transformedData = {};
|
|
198
|
+
for (const transform of step.transform || []) {
|
|
199
|
+
const input = resolveTemplate(transform.input, context);
|
|
200
|
+
const transformedValue = applyTransformation(transform.operation, input, transform.parameters);
|
|
201
|
+
transformedData[transform.name] = transformedValue;
|
|
202
|
+
}
|
|
203
|
+
return transformedData;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Execute condition step
|
|
207
|
+
*/
|
|
208
|
+
function executeConditionStep(step, context) {
|
|
209
|
+
const condition = step.condition;
|
|
210
|
+
const fieldValue = resolveTemplate(condition.field, context);
|
|
211
|
+
const compareValue = resolveTemplate(condition.value, context);
|
|
212
|
+
let result = false;
|
|
213
|
+
switch (condition.operator) {
|
|
214
|
+
case 'equals':
|
|
215
|
+
result = fieldValue === compareValue;
|
|
216
|
+
break;
|
|
217
|
+
case 'not_equals':
|
|
218
|
+
result = fieldValue !== compareValue;
|
|
219
|
+
break;
|
|
220
|
+
case 'contains':
|
|
221
|
+
result = String(fieldValue).includes(String(compareValue));
|
|
222
|
+
break;
|
|
223
|
+
case 'exists':
|
|
224
|
+
result = fieldValue !== undefined && fieldValue !== null;
|
|
225
|
+
break;
|
|
226
|
+
default:
|
|
227
|
+
result = false;
|
|
228
|
+
}
|
|
229
|
+
return { conditionResult: result, fieldValue, compareValue };
|
|
230
|
+
}
|
|
231
|
+
// ============ Helper Functions ============
|
|
232
|
+
/**
|
|
233
|
+
* Apply transformation to a value
|
|
234
|
+
*/
|
|
235
|
+
function applyTransformation(operation, input, parameters = {}) {
|
|
236
|
+
switch (operation) {
|
|
237
|
+
case 'base64':
|
|
238
|
+
return Buffer.from(String(input)).toString('base64');
|
|
239
|
+
case 'concat':
|
|
240
|
+
return Array.isArray(input) ? input.join('') : String(input);
|
|
241
|
+
case 'hash':
|
|
242
|
+
return crypto_1.default.createHash('sha256').update(String(input)).digest('hex');
|
|
243
|
+
case 'json_parse':
|
|
244
|
+
return JSON.parse(String(input));
|
|
245
|
+
case 'url_encode':
|
|
246
|
+
return encodeURIComponent(String(input));
|
|
247
|
+
default:
|
|
248
|
+
return input;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Resolve template variables in a string
|
|
253
|
+
*/
|
|
254
|
+
function resolveTemplate(template, context) {
|
|
255
|
+
if (typeof template !== 'string')
|
|
256
|
+
return template;
|
|
257
|
+
return template.replace(/\{\{(.+?)\}\}/g, (match, path) => {
|
|
258
|
+
const value = resolvePath(path.trim(), context);
|
|
259
|
+
return value !== undefined ? String(value) : match;
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Resolve template variables in an object
|
|
264
|
+
*/
|
|
265
|
+
function resolveTemplateObject(obj, context) {
|
|
266
|
+
if (typeof obj === 'string') {
|
|
267
|
+
return resolveTemplate(obj, context);
|
|
268
|
+
}
|
|
269
|
+
else if (Array.isArray(obj)) {
|
|
270
|
+
return obj.map(item => resolveTemplateObject(item, context));
|
|
271
|
+
}
|
|
272
|
+
else if (typeof obj === 'object' && obj !== null) {
|
|
273
|
+
const resolved = {};
|
|
274
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
275
|
+
resolved[key] = resolveTemplateObject(value, context);
|
|
276
|
+
}
|
|
277
|
+
return resolved;
|
|
278
|
+
}
|
|
279
|
+
return obj;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Resolve a path in the context (e.g., "steps.step1.token")
|
|
283
|
+
*/
|
|
284
|
+
function resolvePath(path, context) {
|
|
285
|
+
const parts = path.split('.');
|
|
286
|
+
let current = context;
|
|
287
|
+
for (const part of parts) {
|
|
288
|
+
if (current && typeof current === 'object') {
|
|
289
|
+
current = current[part];
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return current;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Extract value using JSONPath (simplified implementation)
|
|
299
|
+
*/
|
|
300
|
+
function extractJsonPath(data, path) {
|
|
301
|
+
if (path.startsWith('$.')) {
|
|
302
|
+
path = path.substring(2);
|
|
303
|
+
}
|
|
304
|
+
return resolvePath(path, data);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Generate auth data from outputs
|
|
308
|
+
*/
|
|
309
|
+
function generateAuthData(outputs, context) {
|
|
310
|
+
const authData = {
|
|
311
|
+
headers: {},
|
|
312
|
+
queryParams: {},
|
|
313
|
+
bodyParams: {}
|
|
314
|
+
};
|
|
315
|
+
for (const output of outputs) {
|
|
316
|
+
const value = resolveTemplate(output.value, context);
|
|
317
|
+
switch (output.type) {
|
|
318
|
+
case 'header':
|
|
319
|
+
authData.headers[output.name] = value;
|
|
320
|
+
break;
|
|
321
|
+
case 'query_param':
|
|
322
|
+
authData.queryParams[output.name] = value;
|
|
323
|
+
break;
|
|
324
|
+
case 'body_param':
|
|
325
|
+
authData.bodyParams[output.name] = value;
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return authData;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Apply auth data to request config (headers, query params)
|
|
333
|
+
*/
|
|
334
|
+
function applyAuthToRequest(requestConfig, authData) {
|
|
335
|
+
// Apply auth headers
|
|
336
|
+
if (authData.headers && Object.keys(authData.headers).length > 0) {
|
|
337
|
+
requestConfig.headers = {
|
|
338
|
+
...requestConfig.headers,
|
|
339
|
+
...authData.headers
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
// Apply query params (append to URL)
|
|
343
|
+
if (authData.queryParams && Object.keys(authData.queryParams).length > 0) {
|
|
344
|
+
const url = new URL(requestConfig.url);
|
|
345
|
+
for (const [key, value] of Object.entries(authData.queryParams)) {
|
|
346
|
+
url.searchParams.set(key, value);
|
|
347
|
+
}
|
|
348
|
+
requestConfig.url = url.toString();
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
//# sourceMappingURL=AuthFlowExecutor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthFlowExecutor.js","sourceRoot":"","sources":["../src/AuthFlowExecutor.ts"],"names":[],"mappings":"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"}
|
package/dist/AxiosGenerator.js
CHANGED
|
@@ -168,21 +168,21 @@ function generateTestFile(test, baseUrl) {
|
|
|
168
168
|
const description = test.description ? `\n * ${test.description}` : '';
|
|
169
169
|
const tags = test.tags?.length ? `\n * Tags: ${test.tags.join(', ')}` : '';
|
|
170
170
|
const priority = test.priority ? `\n * Priority: ${test.priority}` : '';
|
|
171
|
-
return `/**
|
|
172
|
-
* Test: ${test.name}${description}${tags}${priority}
|
|
173
|
-
*
|
|
174
|
-
* Generated by Qate CLI
|
|
175
|
-
* Do not edit manually - regenerate using: qate export
|
|
176
|
-
*/
|
|
177
|
-
|
|
178
|
-
import axios from 'axios';
|
|
179
|
-
import { describe, test, expect } from 'vitest';
|
|
180
|
-
|
|
181
|
-
const BASE_URL = '${escapeString(baseUrl)}';
|
|
182
|
-
|
|
183
|
-
describe('${escapeString(test.name)}', () => {
|
|
184
|
-
${stepCode}
|
|
185
|
-
});
|
|
171
|
+
return `/**
|
|
172
|
+
* Test: ${test.name}${description}${tags}${priority}
|
|
173
|
+
*
|
|
174
|
+
* Generated by Qate CLI
|
|
175
|
+
* Do not edit manually - regenerate using: qate export
|
|
176
|
+
*/
|
|
177
|
+
|
|
178
|
+
import axios from 'axios';
|
|
179
|
+
import { describe, test, expect } from 'vitest';
|
|
180
|
+
|
|
181
|
+
const BASE_URL = '${escapeString(baseUrl)}';
|
|
182
|
+
|
|
183
|
+
describe('${escapeString(test.name)}', () => {
|
|
184
|
+
${stepCode}
|
|
185
|
+
});
|
|
186
186
|
`;
|
|
187
187
|
}
|
|
188
188
|
/**
|
|
@@ -211,14 +211,14 @@ function generatePackageJson(name) {
|
|
|
211
211
|
* Generate vitest.config.ts
|
|
212
212
|
*/
|
|
213
213
|
function generateVitestConfig() {
|
|
214
|
-
return `import { defineConfig } from 'vitest/config';
|
|
215
|
-
|
|
216
|
-
export default defineConfig({
|
|
217
|
-
test: {
|
|
218
|
-
globals: true,
|
|
219
|
-
testTimeout: 30000,
|
|
220
|
-
},
|
|
221
|
-
});
|
|
214
|
+
return `import { defineConfig } from 'vitest/config';
|
|
215
|
+
|
|
216
|
+
export default defineConfig({
|
|
217
|
+
test: {
|
|
218
|
+
globals: true,
|
|
219
|
+
testTimeout: 30000,
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
222
|
`;
|
|
223
223
|
}
|
|
224
224
|
/**
|
|
@@ -250,11 +250,11 @@ function generateAxiosSummary(exportData) {
|
|
|
250
250
|
const appType = exportData.application?.type || 'unknown';
|
|
251
251
|
const type = exportData.type === 'testsequence' ? 'Test Sequence' : 'Test Set';
|
|
252
252
|
const name = exportData.testSequence?.name || exportData.testSet?.name || 'Unknown';
|
|
253
|
-
return `
|
|
254
|
-
Generating Axios tests from ${type}: "${name}"
|
|
255
|
-
Application: ${appName} (${appType}) - ${appUrl}
|
|
256
|
-
Tests: ${testCount}
|
|
257
|
-
Total Steps: ${stepCount}
|
|
253
|
+
return `
|
|
254
|
+
Generating Axios tests from ${type}: "${name}"
|
|
255
|
+
Application: ${appName} (${appType}) - ${appUrl}
|
|
256
|
+
Tests: ${testCount}
|
|
257
|
+
Total Steps: ${stepCount}
|
|
258
258
|
`;
|
|
259
259
|
}
|
|
260
260
|
//# sourceMappingURL=AxiosGenerator.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TestResult, ExecutionStatus } from './client';
|
|
2
|
+
/**
|
|
3
|
+
* Generate JUnit XML from TestResult[] (REST/SOAP local execution).
|
|
4
|
+
* Each TestResult becomes a <testsuite>, each StepResult becomes a <testcase>.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateJunitXml(results: TestResult[] | null | undefined, suiteName?: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Generate JUnit XML from ExecutionStatus (desktop app polling).
|
|
9
|
+
* No step-level detail available — each test becomes a single <testcase>.
|
|
10
|
+
*/
|
|
11
|
+
export declare function generateJunitXmlFromStatus(status: ExecutionStatus | null | undefined, suiteName?: string): string;
|
|
12
|
+
//# sourceMappingURL=JunitXmlGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JunitXmlGenerator.d.ts","sourceRoot":"","sources":["../src/JunitXmlGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAiBvD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAqFrG;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBjH"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateJunitXml = generateJunitXml;
|
|
4
|
+
exports.generateJunitXmlFromStatus = generateJunitXmlFromStatus;
|
|
5
|
+
function escapeXml(str) {
|
|
6
|
+
if (str == null)
|
|
7
|
+
return '';
|
|
8
|
+
return String(str)
|
|
9
|
+
.replace(/&/g, '&')
|
|
10
|
+
.replace(/</g, '<')
|
|
11
|
+
.replace(/>/g, '>')
|
|
12
|
+
.replace(/"/g, '"')
|
|
13
|
+
.replace(/'/g, ''');
|
|
14
|
+
}
|
|
15
|
+
function safeDuration(duration) {
|
|
16
|
+
if (duration == null || isNaN(duration))
|
|
17
|
+
return '0.000';
|
|
18
|
+
return (duration / 1000).toFixed(3);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generate JUnit XML from TestResult[] (REST/SOAP local execution).
|
|
22
|
+
* Each TestResult becomes a <testsuite>, each StepResult becomes a <testcase>.
|
|
23
|
+
*/
|
|
24
|
+
function generateJunitXml(results, suiteName) {
|
|
25
|
+
const safeResults = Array.isArray(results) ? results : [];
|
|
26
|
+
const safeSuiteName = suiteName || 'Qate Tests';
|
|
27
|
+
const timestamp = new Date().toISOString();
|
|
28
|
+
let totalTests = 0;
|
|
29
|
+
let totalFailures = 0;
|
|
30
|
+
let totalErrors = 0;
|
|
31
|
+
let totalTime = 0;
|
|
32
|
+
const suites = [];
|
|
33
|
+
for (const result of safeResults) {
|
|
34
|
+
const testName = result?.testName || 'Unknown Test';
|
|
35
|
+
const steps = Array.isArray(result?.steps) && result.steps.length > 0 ? result.steps : null;
|
|
36
|
+
if (steps) {
|
|
37
|
+
// Create testcases from steps
|
|
38
|
+
let suiteTests = 0;
|
|
39
|
+
let suiteFailures = 0;
|
|
40
|
+
let suiteErrors = 0;
|
|
41
|
+
let suiteTime = 0;
|
|
42
|
+
const testcases = [];
|
|
43
|
+
for (let i = 0; i < steps.length; i++) {
|
|
44
|
+
const step = steps[i];
|
|
45
|
+
const stepName = step?.description || `Step ${i + 1}`;
|
|
46
|
+
const stepDuration = safeDuration(step?.duration);
|
|
47
|
+
suiteTime += (step?.duration != null && !isNaN(step.duration)) ? step.duration : 0;
|
|
48
|
+
suiteTests++;
|
|
49
|
+
let inner = '';
|
|
50
|
+
if (step?.status === 'failed') {
|
|
51
|
+
suiteFailures++;
|
|
52
|
+
const msg = escapeXml(step.error || 'Test step failed');
|
|
53
|
+
inner = `\n <failure message="${msg}" type="TestFailure">${msg}</failure>`;
|
|
54
|
+
}
|
|
55
|
+
else if (step?.status === 'error') {
|
|
56
|
+
suiteErrors++;
|
|
57
|
+
const msg = escapeXml(step.error || 'Test step error');
|
|
58
|
+
inner = `\n <error message="${msg}" type="TestError">${msg}</error>`;
|
|
59
|
+
}
|
|
60
|
+
testcases.push(` <testcase name="${escapeXml(stepName)}" classname="${escapeXml(testName)}" time="${stepDuration}">${inner}\n </testcase>`);
|
|
61
|
+
}
|
|
62
|
+
totalTests += suiteTests;
|
|
63
|
+
totalFailures += suiteFailures;
|
|
64
|
+
totalErrors += suiteErrors;
|
|
65
|
+
totalTime += suiteTime;
|
|
66
|
+
suites.push(` <testsuite name="${escapeXml(testName)}" tests="${suiteTests}" failures="${suiteFailures}" errors="${suiteErrors}" time="${safeDuration(suiteTime)}" timestamp="${timestamp}">\n${testcases.join('\n')}\n </testsuite>`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// No steps — create a single testcase from test-level data
|
|
70
|
+
totalTests++;
|
|
71
|
+
const duration = (result?.duration != null && !isNaN(result.duration)) ? result.duration : 0;
|
|
72
|
+
totalTime += duration;
|
|
73
|
+
let inner = '';
|
|
74
|
+
if (result?.status === 'failed') {
|
|
75
|
+
totalFailures++;
|
|
76
|
+
inner = `\n <failure message="Test failed" type="TestFailure">Test failed</failure>`;
|
|
77
|
+
}
|
|
78
|
+
else if (result?.status === 'error') {
|
|
79
|
+
totalErrors++;
|
|
80
|
+
inner = `\n <error message="Test error" type="TestError">Test error</error>`;
|
|
81
|
+
}
|
|
82
|
+
suites.push(` <testsuite name="${escapeXml(testName)}" tests="1" failures="${result?.status === 'failed' ? 1 : 0}" errors="${result?.status === 'error' ? 1 : 0}" time="${safeDuration(duration)}" timestamp="${timestamp}">\n <testcase name="${escapeXml(testName)}" classname="${escapeXml(testName)}" time="${safeDuration(duration)}">${inner}\n </testcase>\n </testsuite>`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const lines = [
|
|
86
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
87
|
+
`<testsuites name="${escapeXml(safeSuiteName)}" tests="${totalTests}" failures="${totalFailures}" errors="${totalErrors}" time="${safeDuration(totalTime)}" timestamp="${timestamp}">`,
|
|
88
|
+
...suites,
|
|
89
|
+
'</testsuites>',
|
|
90
|
+
''
|
|
91
|
+
];
|
|
92
|
+
return lines.join('\n');
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Generate JUnit XML from ExecutionStatus (desktop app polling).
|
|
96
|
+
* No step-level detail available — each test becomes a single <testcase>.
|
|
97
|
+
*/
|
|
98
|
+
function generateJunitXmlFromStatus(status, suiteName) {
|
|
99
|
+
if (!status) {
|
|
100
|
+
return generateJunitXml([], suiteName);
|
|
101
|
+
}
|
|
102
|
+
const tests = Array.isArray(status.tests) ? status.tests : [];
|
|
103
|
+
const results = tests.map((t) => ({
|
|
104
|
+
testId: t?.testId || '',
|
|
105
|
+
testName: t?.testName || 'Unknown Test',
|
|
106
|
+
status: (t?.status === 'passed' || t?.status === 'failed' || t?.status === 'error')
|
|
107
|
+
? t.status
|
|
108
|
+
: 'error',
|
|
109
|
+
duration: (t?.executionTime != null && !isNaN(t.executionTime)) ? t.executionTime : 0,
|
|
110
|
+
steps: undefined
|
|
111
|
+
}));
|
|
112
|
+
return generateJunitXml(results, suiteName || status.testSetName || status.sequenceName || 'Qate Tests');
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=JunitXmlGenerator.js.map
|