@skyramp/skyramp 0.4.91 → 0.4.92
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/lib/dev-darwin-amd64.dylib +0 -0
- package/lib/dev-darwin-amd64.h +1 -1
- package/lib/dev-darwin-arm64.dylib +0 -0
- package/lib/dev-darwin-arm64.h +1 -1
- package/lib/dev-linux-386.h +1 -1
- package/lib/dev-linux-386.so +0 -0
- package/lib/dev-linux-amd64.h +1 -1
- package/lib/dev-linux-amd64.so +0 -0
- package/lib/dev-windows-amd64.dll +0 -0
- package/lib/dev-windows-amd64.h +1 -1
- package/package.json +1 -1
- package/src/classes/Asserts.d.ts +16 -0
- package/src/classes/Asserts.js +41 -0
- package/src/classes/GrpcEndpoint.js +11 -3
- package/src/classes/RequestValue.d.ts +2 -2
- package/src/classes/RequestValue.js +1 -1
- package/src/classes/ResponseValue.js +1 -1
- package/src/classes/Scenario.d.ts +38 -1
- package/src/classes/Scenario.js +120 -33
- package/src/classes/SkyrampClient.d.ts +26 -16
- package/src/classes/SkyrampClient.js +74 -23
- package/src/classes/Step.d.ts +28 -0
- package/src/classes/Step.js +113 -0
- package/src/index.d.ts +1 -1
- package/src/index.js +4 -0
- package/src/utils.js +12 -11
|
Binary file
|
package/lib/dev-darwin-amd64.h
CHANGED
|
@@ -123,7 +123,7 @@ extern char* registerUserWrapper(char* provider, char* email, char* code);
|
|
|
123
123
|
extern struct oauthresponse runOAuthLoopback(char* provider, GoInt port);
|
|
124
124
|
extern char* validateTokenWrapper(char* userToken);
|
|
125
125
|
extern char* generateUserTokenWrapper(char* provider, char* email, char* oauthToken);
|
|
126
|
-
extern struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName);
|
|
126
|
+
extern struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName, char* testServiceAlias);
|
|
127
127
|
extern char* newDeleteDockerSkyrampWorkerWrapper(char* containerName);
|
|
128
128
|
extern char* runTesterCurlWrapper(char* namespace, char* kubePath, char* kubeContext, char* clusterName, char* address, char* request);
|
|
129
129
|
extern char* newGrpcEndpointWrapper(char* name, char* serviceName, GoInt port, char* inputFile);
|
|
Binary file
|
package/lib/dev-darwin-arm64.h
CHANGED
|
@@ -123,7 +123,7 @@ extern char* registerUserWrapper(char* provider, char* email, char* code);
|
|
|
123
123
|
extern struct oauthresponse runOAuthLoopback(char* provider, GoInt port);
|
|
124
124
|
extern char* validateTokenWrapper(char* userToken);
|
|
125
125
|
extern char* generateUserTokenWrapper(char* provider, char* email, char* oauthToken);
|
|
126
|
-
extern struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName);
|
|
126
|
+
extern struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName, char* testServiceAlias);
|
|
127
127
|
extern char* newDeleteDockerSkyrampWorkerWrapper(char* containerName);
|
|
128
128
|
extern char* runTesterCurlWrapper(char* namespace, char* kubePath, char* kubeContext, char* clusterName, char* address, char* request);
|
|
129
129
|
extern char* newGrpcEndpointWrapper(char* name, char* serviceName, GoInt port, char* inputFile);
|
package/lib/dev-linux-386.h
CHANGED
|
@@ -123,7 +123,7 @@ extern char* registerUserWrapper(char* provider, char* email, char* code);
|
|
|
123
123
|
extern struct oauthresponse runOAuthLoopback(char* provider, GoInt port);
|
|
124
124
|
extern char* validateTokenWrapper(char* userToken);
|
|
125
125
|
extern char* generateUserTokenWrapper(char* provider, char* email, char* oauthToken);
|
|
126
|
-
extern struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName);
|
|
126
|
+
extern struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName, char* testServiceAlias);
|
|
127
127
|
extern char* newDeleteDockerSkyrampWorkerWrapper(char* containerName);
|
|
128
128
|
extern char* runTesterCurlWrapper(char* namespace, char* kubePath, char* kubeContext, char* clusterName, char* address, char* request);
|
|
129
129
|
extern char* newGrpcEndpointWrapper(char* name, char* serviceName, GoInt port, char* inputFile);
|
package/lib/dev-linux-386.so
CHANGED
|
Binary file
|
package/lib/dev-linux-amd64.h
CHANGED
|
@@ -123,7 +123,7 @@ extern char* registerUserWrapper(char* provider, char* email, char* code);
|
|
|
123
123
|
extern struct oauthresponse runOAuthLoopback(char* provider, GoInt port);
|
|
124
124
|
extern char* validateTokenWrapper(char* userToken);
|
|
125
125
|
extern char* generateUserTokenWrapper(char* provider, char* email, char* oauthToken);
|
|
126
|
-
extern struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName);
|
|
126
|
+
extern struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName, char* testServiceAlias);
|
|
127
127
|
extern char* newDeleteDockerSkyrampWorkerWrapper(char* containerName);
|
|
128
128
|
extern char* runTesterCurlWrapper(char* namespace, char* kubePath, char* kubeContext, char* clusterName, char* address, char* request);
|
|
129
129
|
extern char* newGrpcEndpointWrapper(char* name, char* serviceName, GoInt port, char* inputFile);
|
package/lib/dev-linux-amd64.so
CHANGED
|
Binary file
|
|
Binary file
|
package/lib/dev-windows-amd64.h
CHANGED
|
@@ -123,7 +123,7 @@ extern __declspec(dllexport) char* registerUserWrapper(char* provider, char* ema
|
|
|
123
123
|
extern __declspec(dllexport) struct oauthresponse runOAuthLoopback(char* provider, GoInt port);
|
|
124
124
|
extern __declspec(dllexport) char* validateTokenWrapper(char* userToken);
|
|
125
125
|
extern __declspec(dllexport) char* generateUserTokenWrapper(char* provider, char* email, char* oauthToken);
|
|
126
|
-
extern __declspec(dllexport) struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName);
|
|
126
|
+
extern __declspec(dllexport) struct worker_info newStartDockerSkyrampWorkerWrapper(char* image, char* tag, GoInt hostPort, char* targetNetworkName, char* testServiceAlias);
|
|
127
127
|
extern __declspec(dllexport) char* newDeleteDockerSkyrampWorkerWrapper(char* containerName);
|
|
128
128
|
extern __declspec(dllexport) char* runTesterCurlWrapper(char* namespace, char* kubePath, char* kubeContext, char* clusterName, char* address, char* request);
|
|
129
129
|
extern __declspec(dllexport) char* newGrpcEndpointWrapper(char* name, char* serviceName, GoInt port, char* inputFile);
|
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} AssertOptions
|
|
3
|
+
* @property {string} assertValue - The value to be asserted.
|
|
4
|
+
* @property {string} expectedValue - The expected value for the assertion.
|
|
5
|
+
* @property {string} assertStepName - The name of the step.
|
|
6
|
+
* @property {string} description - The description of the assertion.
|
|
7
|
+
*/
|
|
8
|
+
interface AssertOptions {
|
|
9
|
+
assertValue: string;
|
|
10
|
+
expectedValue: string;
|
|
11
|
+
assertStepName: string;
|
|
12
|
+
description: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class Asserts {
|
|
15
|
+
constructor(options: AssertOptions);
|
|
16
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `Assert` class represents an assertion to be used in a test step.
|
|
3
|
+
* @class
|
|
4
|
+
*/
|
|
5
|
+
class Assert {
|
|
6
|
+
/**
|
|
7
|
+
* Initialize a new instance of an Assert.
|
|
8
|
+
* @constructor
|
|
9
|
+
* @param {Object} option - The options for initializing the Assert object.
|
|
10
|
+
* @param {*} option.assertValue - The value to be asserted.
|
|
11
|
+
* @param {*} option.assertExpectedValue - The expected value for the assertion.
|
|
12
|
+
* @param {string} option.stepName - The name of the step.
|
|
13
|
+
* @param {string} option.description - The description of the assertion.
|
|
14
|
+
*/
|
|
15
|
+
constructor(option) {
|
|
16
|
+
this.assertValue = option.assertValue;
|
|
17
|
+
this.expectedValue = option.assertExpectedValue;
|
|
18
|
+
this.name = option.stepName;
|
|
19
|
+
this.description = option.description;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Convert the assertion to a JSON object.
|
|
24
|
+
* @returns {Object} The JSON representation of the assertion.
|
|
25
|
+
*/
|
|
26
|
+
toJson() {
|
|
27
|
+
return {
|
|
28
|
+
asserts: `${this.assertValue} == ${this.expectedValue}`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Convert the assertion to a string representation.
|
|
34
|
+
* @returns {string} The string representation of the assertion.
|
|
35
|
+
*/
|
|
36
|
+
toAssert() {
|
|
37
|
+
return `${this.assertValue} == ${this.expectedValue}`
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = Assert;
|
|
@@ -16,9 +16,17 @@ class GrpcEndpoint extends Endpoint {
|
|
|
16
16
|
* @param {string} pbFile - The protocol buffer file containing the API schema definition.
|
|
17
17
|
* @param {string} endpointAddress - The endpoint address.
|
|
18
18
|
*/
|
|
19
|
-
constructor(
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
constructor(...args) {
|
|
20
|
+
let name, service, port, pbFile, endpointAddress;
|
|
21
|
+
if (args.length === 1 && typeof args[0] === 'object') {
|
|
22
|
+
({ name, service, port, pbFile, endpointAddress } = args[0]);
|
|
23
|
+
} else if (args.length >= 4) {
|
|
24
|
+
[name, service, port, pbFile, endpointAddress] = args;
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error('Invalid arguments for GrpcEndpoint constructor');
|
|
27
|
+
}
|
|
28
|
+
const grpcEndPointData = newGrpcEndpointWrapper(name, service, port, pbFile, endpointAddress);
|
|
29
|
+
super(grpcEndPointData, endpointAddress);
|
|
22
30
|
}
|
|
23
31
|
}
|
|
24
32
|
|
|
@@ -8,14 +8,14 @@ interface RequestValueOptions {
|
|
|
8
8
|
methodName?: string;
|
|
9
9
|
params?: RestParam[];
|
|
10
10
|
headers?: {[headerName: string]: string},
|
|
11
|
-
vars?:
|
|
11
|
+
vars?: {[ var_: string]: string | number};
|
|
12
12
|
blob?: string;
|
|
13
13
|
graphqlParam?: string;
|
|
14
14
|
javascriptPath?: string;
|
|
15
15
|
javascriptFunction?: string;
|
|
16
16
|
}
|
|
17
17
|
export declare class RequestValue {
|
|
18
|
-
constructor(options:
|
|
18
|
+
constructor(options: RequestValueOptions)
|
|
19
19
|
asRequestDict() : RequestValue
|
|
20
20
|
setCookieValue(cookieValue: string) : void
|
|
21
21
|
setResponse(responseValue: ResponseValue) : void
|
|
@@ -30,7 +30,7 @@ class RequestValue {
|
|
|
30
30
|
this.params = options.params;
|
|
31
31
|
this.headers = options.headers;
|
|
32
32
|
this.vars = options.vars;
|
|
33
|
-
this.blob = options.blob;
|
|
33
|
+
this.blob = options.blob ? JSON.stringify(options.blob) : undefined;
|
|
34
34
|
this.graphqlParam = options.graphqlParam;
|
|
35
35
|
this.javascriptPath = options.javascriptPath;
|
|
36
36
|
this.javascript = options.javascriptFunction;
|
|
@@ -30,7 +30,7 @@ class ResponseValue {
|
|
|
30
30
|
this.params = options.params;
|
|
31
31
|
this.headers = options.headers;
|
|
32
32
|
this.vars = options.vars;
|
|
33
|
-
this.blob = options.blob;
|
|
33
|
+
this.blob = options.blob ? JSON.stringify(options.blob) : undefined;
|
|
34
34
|
this.javascriptPath = options.javascriptPath;
|
|
35
35
|
this.javascript = options.javascriptFunction;
|
|
36
36
|
|
|
@@ -1,11 +1,48 @@
|
|
|
1
|
+
import { Asserts } from './Asserts';
|
|
1
2
|
import { RequestValue } from './RequestValue';
|
|
2
3
|
import { Endpoint } from './Endpoint';
|
|
4
|
+
import { StepConfig } from './Step';
|
|
5
|
+
|
|
6
|
+
interface ScenarioOptions {
|
|
7
|
+
name: string,
|
|
8
|
+
startAt?: string,
|
|
9
|
+
headers?: {[headerName: string]: string},
|
|
10
|
+
vars?: {[ var_: string]: string | number},
|
|
11
|
+
ignore?: boolean,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface RequestOption {
|
|
15
|
+
request: RequestValue
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface AssertOption {
|
|
19
|
+
assert: Asserts
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface ScenarioOption {
|
|
23
|
+
scenario: Scenario
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
interface AddRequestOption extends RequestOption, StepConfig {
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface AddAssertOption extends AssertOption, StepConfig {
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface AddScenarioOption extends ScenarioOption, StepConfig {
|
|
34
|
+
}
|
|
35
|
+
|
|
3
36
|
export declare class Scenario {
|
|
4
37
|
constructor(name: string);
|
|
38
|
+
constructor(options: ScenarioOptions);
|
|
5
39
|
addRequest(endpoint: Endpoint, methodName: string, requestObject?: string, dynamic?: boolean): string;
|
|
6
40
|
addRequestFromFile(endpoint: Endpoint, methodName: string, requestFile: string): string;
|
|
7
41
|
buildRequestsFromEndpoint(endpoint: Endpoint): void;
|
|
8
42
|
addAssertEqual(value1: string, value2: string): string;
|
|
9
43
|
writeTestConfigurationToFile(): Promise<void>;
|
|
10
44
|
addRequestV1(request: RequestValue): string;
|
|
11
|
-
|
|
45
|
+
addRequestV2(options: AddRequestOption): string;
|
|
46
|
+
addScenarioV2(options: AddScenarioOption): string;
|
|
47
|
+
addAssertV2(options: AddAssertOption): string;
|
|
48
|
+
}
|
package/src/classes/Scenario.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
const lib = require('../lib');
|
|
2
|
-
const { createTestDescriptionFromScenario, getYamlBytes, readDataFromFile
|
|
2
|
+
const { createTestDescriptionFromScenario, getYamlBytes, readDataFromFile } = require('../utils');
|
|
3
|
+
const Asserts = require('./Asserts');
|
|
4
|
+
const RequestValue = require('./RequestValue');
|
|
5
|
+
const Step = require('./Step');
|
|
3
6
|
const buildRequestsWrapper = lib.func('buildRequestsWrapper', 'string', ['string']);
|
|
4
7
|
const writeTestDescriptionWrapper = lib.func('writeTestDescriptionWrapper', 'string', ['string', 'string']);
|
|
5
8
|
|
|
@@ -8,50 +11,121 @@ const writeTestDescriptionWrapper = lib.func('writeTestDescriptionWrapper', 'str
|
|
|
8
11
|
* @class
|
|
9
12
|
*/
|
|
10
13
|
class Scenario {
|
|
14
|
+
static requests = [];
|
|
15
|
+
static scenarios = [];
|
|
16
|
+
static services = [];
|
|
17
|
+
static endpoints = [];
|
|
18
|
+
|
|
11
19
|
/**
|
|
12
20
|
* Initializes a new instance of the Scenario class with the given name.
|
|
13
21
|
* @constructor
|
|
22
|
+
*
|
|
14
23
|
* @param {string} name - The name of the scenario.
|
|
15
24
|
*/
|
|
16
|
-
constructor(
|
|
17
|
-
|
|
25
|
+
constructor(...args) {
|
|
26
|
+
if (args.length === 1 && typeof args[0] === 'object') {
|
|
27
|
+
const { name, startAt = 1, headers, vars, ignore } = args[0];
|
|
28
|
+
Object.assign(this, { name, startAt, headers, vars, ignore });
|
|
29
|
+
} else if (args.length === 1 && typeof args[0] === 'string') {
|
|
30
|
+
this.name = args[0];
|
|
31
|
+
}
|
|
18
32
|
this.steps = [];
|
|
19
|
-
this.services = [];
|
|
20
|
-
this.endpoints = [];
|
|
21
|
-
this.requests = [];
|
|
22
|
-
|
|
23
|
-
this.testDescriptionV1 = {
|
|
24
|
-
version: SKYRAMP_YAML_VERSION,
|
|
25
|
-
services: [],
|
|
26
|
-
endpoints: [],
|
|
27
|
-
steps: [],
|
|
28
|
-
requestss: [],
|
|
29
|
-
};
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
|
-
* Adds a request to the scenario
|
|
34
|
-
*
|
|
35
|
-
* @
|
|
36
|
+
* Adds a request to the scenario.
|
|
37
|
+
*
|
|
38
|
+
* @param {AddRequestOption} option - The options for adding the request.
|
|
39
|
+
* @returns {string} - The name of the request.
|
|
40
|
+
* @throws {Error} - Throws an error if the option is not of type RequestValue or an object with a request property of type RequestValue.
|
|
36
41
|
*/
|
|
37
|
-
addRequestV1(
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
addRequestV1(option) {
|
|
43
|
+
if (!(option instanceof RequestValue) && !(option.request instanceof RequestValue)) {
|
|
44
|
+
throw new Error('Invalid argument: option must be of type RequestValue or an object with a request property of type RequestValue');
|
|
45
|
+
}
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
const request = option instanceof RequestValue ? option : option.request;
|
|
48
|
+
option = { ...option, step: request };
|
|
49
|
+
|
|
50
|
+
const step = new Step(option);
|
|
51
|
+
this.steps.push(step.toJson());
|
|
52
|
+
Scenario.requests.push(request.asRequestDict());
|
|
53
|
+
|
|
54
|
+
const newService = request.endpointDescriptor.services[0];
|
|
55
|
+
if (!Scenario.services.some(s => s.name === newService.name)) {
|
|
56
|
+
Scenario.services.push(newService);
|
|
43
57
|
}
|
|
44
58
|
|
|
45
|
-
if (!
|
|
46
|
-
|
|
59
|
+
if (!Scenario.endpoints.find(ep => ep === request.endpointDescriptor.endpoint)) {
|
|
60
|
+
Scenario.endpoints.push(request.endpointDescriptor.endpoint);
|
|
47
61
|
}
|
|
48
62
|
|
|
49
63
|
return request.name;
|
|
50
64
|
}
|
|
51
65
|
|
|
52
|
-
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Prepares a test description by creating a data structure with a root scenario and child scenarios for a test description.
|
|
69
|
+
*
|
|
70
|
+
* @returns {Object} - The test description object containing the root scenario, child scenarios, endpoints, services, and requests.
|
|
71
|
+
*/
|
|
72
|
+
prepareTestDescription() {
|
|
73
|
+
let scenarios = []
|
|
74
|
+
// add ourself as root scenario
|
|
75
|
+
scenarios.push({
|
|
76
|
+
name: this.name,
|
|
77
|
+
...(this.vars != undefined && { vars: this.vars }),
|
|
78
|
+
...(this.headers != undefined && { headers: this.headers }),
|
|
79
|
+
...(this.ignore != undefined && { ignore: this.ignore }),
|
|
80
|
+
steps: this.steps,
|
|
81
|
+
})
|
|
82
|
+
// add all client scenarios
|
|
83
|
+
Scenario.scenarios.forEach((scenario) => {
|
|
84
|
+
const s = {
|
|
85
|
+
name: scenario.name,
|
|
86
|
+
...(scenario.vars != undefined && { vars: scenario.vars }),
|
|
87
|
+
...(scenario.headers != undefined && { headers: scenario.headers }),
|
|
88
|
+
...(scenario.ignore != undefined && { ignore: scenario.ignore }),
|
|
89
|
+
steps: scenario.steps,
|
|
90
|
+
}
|
|
91
|
+
scenarios.push(s);
|
|
92
|
+
})
|
|
93
|
+
return {
|
|
94
|
+
name: this.name,
|
|
95
|
+
scenarios: scenarios,
|
|
96
|
+
endpoints: Scenario.endpoints,
|
|
97
|
+
services: Scenario.services,
|
|
98
|
+
requests: Scenario.requests,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
addScenarioV1(option) {
|
|
103
|
+
let scenario = option.scenario;
|
|
104
|
+
if (!(option.scenario instanceof Scenario)) {
|
|
105
|
+
throw new Error('Invalid argument: option.scenario must be of type Scenario');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
option.step = scenario;
|
|
109
|
+
const step = new Step(option);
|
|
110
|
+
this.steps.push(step.toJson());
|
|
111
|
+
|
|
112
|
+
if (!Scenario.scenarios.find(s => s === scenario)) {
|
|
113
|
+
Scenario.scenarios.push(scenario);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
toJson() {
|
|
118
|
+
return {
|
|
119
|
+
steps: this.steps,
|
|
120
|
+
services: this.services,
|
|
121
|
+
endpoints: this.endpoints,
|
|
122
|
+
requests: this.requests,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
addRequest(endpoint, methodName, requestObject = undefined, dynamic = false) {
|
|
53
127
|
this.buildRequestsFromEndpoint(endpoint);
|
|
54
|
-
for (const request of
|
|
128
|
+
for (const request of Scenario.requests) {
|
|
55
129
|
if (request.methodName === methodName) {
|
|
56
130
|
if (dynamic) {
|
|
57
131
|
request.javascriptPath = requestObject;
|
|
@@ -72,18 +146,18 @@ class Scenario {
|
|
|
72
146
|
}
|
|
73
147
|
|
|
74
148
|
buildRequestsFromEndpoint(endpoint) {
|
|
75
|
-
if (
|
|
149
|
+
if (Scenario.endpoints.indexOf(endpoint.endpoint) !== -1) {
|
|
76
150
|
return;
|
|
77
151
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
152
|
+
|
|
153
|
+
Scenario.services.push(...endpoint.services);
|
|
154
|
+
Scenario.endpoints.push(endpoint.endpoint);
|
|
81
155
|
|
|
82
156
|
const yamlContent = getYamlBytes(endpoint.mockDescription);
|
|
83
157
|
const response = buildRequestsWrapper(yamlContent);
|
|
84
158
|
try {
|
|
85
159
|
const requests = JSON.parse(response);
|
|
86
|
-
|
|
160
|
+
Scenario.requests.push(requests[0]);
|
|
87
161
|
} catch (error) {
|
|
88
162
|
throw new Error(response);
|
|
89
163
|
}
|
|
@@ -101,8 +175,21 @@ class Scenario {
|
|
|
101
175
|
return assertion;
|
|
102
176
|
}
|
|
103
177
|
|
|
178
|
+
addAssertV1(option) {
|
|
179
|
+
let assert = new Asserts(option);
|
|
180
|
+
const step = new Step({
|
|
181
|
+
stepName: option.stepName,
|
|
182
|
+
description: option.description,
|
|
183
|
+
if: option.if_,
|
|
184
|
+
step: assert,
|
|
185
|
+
});
|
|
186
|
+
this.steps.push(step.toJson());
|
|
187
|
+
}
|
|
188
|
+
|
|
104
189
|
writeTestConfigurationToFile() {
|
|
105
|
-
const testDescription = createTestDescriptionFromScenario(
|
|
190
|
+
const testDescription = createTestDescriptionFromScenario({
|
|
191
|
+
scenario: this.prepareTestDescription()
|
|
192
|
+
});
|
|
106
193
|
const yamlContent = getYamlBytes(testDescription);
|
|
107
194
|
return new Promise((resolve, reject) => {
|
|
108
195
|
writeTestDescriptionWrapper.async(yamlContent, this.name, (err, res) => {
|
|
@@ -118,4 +205,4 @@ class Scenario {
|
|
|
118
205
|
}
|
|
119
206
|
}
|
|
120
207
|
|
|
121
|
-
module.exports = Scenario;
|
|
208
|
+
module.exports = Scenario;
|
|
@@ -2,6 +2,28 @@ import { ResponseValue } from '..';
|
|
|
2
2
|
import { Endpoint } from './Endpoint';
|
|
3
3
|
import { Scenario } from './Scenario';
|
|
4
4
|
import {TrafficConfig} from './TrafficConfig';
|
|
5
|
+
|
|
6
|
+
interface testerStartV1Options {
|
|
7
|
+
namespace?: string;
|
|
8
|
+
kubePath?: string;
|
|
9
|
+
kubeContext?: string;
|
|
10
|
+
clusterName?: string;
|
|
11
|
+
address?: string;
|
|
12
|
+
scenario: Scenario | [Scenario];
|
|
13
|
+
testName: string;
|
|
14
|
+
globalHeaders?: {[headerName: string]: string};
|
|
15
|
+
generateTestReport?: boolean;
|
|
16
|
+
isDockerenv?: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface MockerApplyV1Options {
|
|
19
|
+
namespace: string;
|
|
20
|
+
kubeConfig: string;
|
|
21
|
+
kubeContext: string;
|
|
22
|
+
clusterName: string;
|
|
23
|
+
address: string;
|
|
24
|
+
response: ResponseValue | ResponseValue[];
|
|
25
|
+
trafficConfig: TrafficConfig;
|
|
26
|
+
}
|
|
5
27
|
export declare class SkyrampClient {
|
|
6
28
|
constructor(kubeconfigPath?: string, clusterName?: string, context?: string, userToken?: string);
|
|
7
29
|
applyLocal(): Promise<void>;
|
|
@@ -11,6 +33,7 @@ export declare class SkyrampClient {
|
|
|
11
33
|
mockerApply(namespace: string, kubePath: string, kubeContext: string, clusterName: string, address: string, endpoint: Endpoint): Promise<void>;
|
|
12
34
|
runDockerSkyrampWorker(workerImage?:string, workerTag?:string, hostPost?:int, targetNetworkName?:string): Promise<void>
|
|
13
35
|
removeDockerSkyrampWorker() : Promise<void>
|
|
36
|
+
mockerApplyV1(options: MockerApplyV1Options): Promise<void>;
|
|
14
37
|
mockerApplyV1(namespace: string, kubePath: string, kubeContext: string, clusterName: string, address: string, response: ResponseValue | ResponseValue[], trafficConfig: TrafficConfig): Promise<void>;
|
|
15
38
|
mockerApplyFromFile(namespace: string, kubePath: string, kubeContext: string, clusterName: string, address: string, filePath: string): Promise<void>;
|
|
16
39
|
applyMockDescription(namespace: string, address: string, mockYamlContent: string): Promise<void>;
|
|
@@ -25,22 +48,9 @@ export declare class SkyrampClient {
|
|
|
25
48
|
globalHeaders: {[headerName: string]: string},
|
|
26
49
|
generateTestReport: boolean,
|
|
27
50
|
isDockerenv: boolean): Promise<void>;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
deployTarget(targetDescription: string, namespace: string, workerImage?: string, localImage?: boolean): Promise<void>;
|
|
32
|
-
deleteTarget(targetDescription: string, namespace: string): Promise<void>;
|
|
33
|
-
|
|
34
|
-
// login / oauth related
|
|
35
|
-
userEmail: string;
|
|
36
|
-
userToken: string;
|
|
37
|
-
userProvider: string;
|
|
38
|
-
getUserToken(): string;
|
|
39
|
-
getUserEmail(): string;
|
|
40
|
-
getUserProvider(): string;
|
|
41
|
-
|
|
42
|
-
setUserToken(userToken: string): void;
|
|
43
|
-
validateToken(userToken: string): Promise<void>;
|
|
51
|
+
|
|
52
|
+
testerStartV1(options: testerStartV1Options): Promise<void>;
|
|
53
|
+
testerStartvalidateToken(userToken: string): Promise<void>;
|
|
44
54
|
readCredential(): Promise<credResponseType>;
|
|
45
55
|
getOAuthURL(provider: string, port: number): string;
|
|
46
56
|
runOAuthLoopback(provider: string, port: number): Promise<oauthResponseType>;
|
|
@@ -40,7 +40,7 @@ const getKubeConfigPath = lib.func('getKubeConfigPath', 'string', []);
|
|
|
40
40
|
const removeLocalWrapper = lib.func('removeLocalWrapper', 'string', []);
|
|
41
41
|
const removeClusterFromConfigWrapper = lib.func('removeClusterFromConfigWrapper', 'string', ['string']);
|
|
42
42
|
// docker related
|
|
43
|
-
const newStartDockerSkyrampWorkerWrapper = lib.func('newStartDockerSkyrampWorkerWrapper', workerInfoType, ['string', 'string', 'int', 'string']);
|
|
43
|
+
const newStartDockerSkyrampWorkerWrapper = lib.func('newStartDockerSkyrampWorkerWrapper', workerInfoType, ['string', 'string', 'int', 'string', 'string']);
|
|
44
44
|
const newDeleteDockerSkyrampWorkerWrapper = lib.func('newDeleteDockerSkyrampWorkerWrapper', 'string', ['string']);
|
|
45
45
|
// tester related
|
|
46
46
|
const runTesterStartWrapper = lib.func('runTesterStartWrapper', testerInfoType, ['string', 'string', 'string', 'string', 'string', 'string', 'bool']);
|
|
@@ -317,9 +317,9 @@ class SkyrampClient {
|
|
|
317
317
|
* @param {string} targetNetworkName - The name of the network to connect the Docker worker to.
|
|
318
318
|
* @returns {Promise} - A Promise that resolves if the Docker worker starts successfully and rejects if there is an error starting the worker.
|
|
319
319
|
*/
|
|
320
|
-
async runDockerSkyrampWorker(workerImage = WORKER_URL, workerTag = WORKER_TAG, hostPost = CONTAINER_PORT, targetNetworkName = "") {
|
|
320
|
+
async runDockerSkyrampWorker(workerImage = WORKER_URL, workerTag = WORKER_TAG, hostPost = CONTAINER_PORT, targetNetworkName = "", testServiceAlias = "") {
|
|
321
321
|
return new Promise((resolve, reject) => {
|
|
322
|
-
newStartDockerSkyrampWorkerWrapper.async(workerImage, workerTag, hostPost, targetNetworkName, (err, res) => {
|
|
322
|
+
newStartDockerSkyrampWorkerWrapper.async(workerImage, workerTag, hostPost, targetNetworkName, testServiceAlias, (err, res) => {
|
|
323
323
|
if (err) {
|
|
324
324
|
reject(err);
|
|
325
325
|
} else if (res.error) {
|
|
@@ -366,12 +366,29 @@ class SkyrampClient {
|
|
|
366
366
|
* @param {object} response - The details of the mock response.
|
|
367
367
|
* @param {object} trafficConfig - The traffic configuration parameters.
|
|
368
368
|
* @returns {Promise} A Promise that resolves when the mock description is successfully applied.
|
|
369
|
+
*
|
|
369
370
|
*/
|
|
370
|
-
async mockerApplyV1(
|
|
371
|
+
async mockerApplyV1(...args) {
|
|
372
|
+
let namespace, kubeConfig, kubeContext, clusterName, address, response, trafficConfig;
|
|
373
|
+
|
|
374
|
+
if (args.length === 1 && typeof args[0] === 'object') {
|
|
375
|
+
const options = args[0];
|
|
376
|
+
namespace = options.namespace;
|
|
377
|
+
kubeConfig = options.kubeConfig;
|
|
378
|
+
kubeContext = options.kubeContext;
|
|
379
|
+
clusterName = options.clusterName;
|
|
380
|
+
address = options.address;
|
|
381
|
+
response = options.response;
|
|
382
|
+
trafficConfig = options.trafficConfig;
|
|
383
|
+
} else {
|
|
384
|
+
[namespace, kubeConfig, kubeContext, clusterName, address, response, trafficConfig] = args;
|
|
385
|
+
}
|
|
386
|
+
|
|
371
387
|
const mockDescription = this.getMockDescriptionv1(response);
|
|
372
388
|
if (trafficConfig instanceof TrafficConfig) {
|
|
373
389
|
mockDescription.mock = { ...mockDescription.mock, ...trafficConfig.toJson() }
|
|
374
390
|
}
|
|
391
|
+
|
|
375
392
|
const yamlContent = getYamlBytes(mockDescription);
|
|
376
393
|
return this.applyMockDescription(namespace, kubeConfig, kubeContext, clusterName, address, yamlContent);
|
|
377
394
|
}
|
|
@@ -397,31 +414,65 @@ class SkyrampClient {
|
|
|
397
414
|
}
|
|
398
415
|
|
|
399
416
|
async testerStart(namespace, kubePath, kubeContext, clusterName, address, scenario) {
|
|
400
|
-
const
|
|
417
|
+
const preparedScenario = scenario.prepareTestDescription();
|
|
418
|
+
const testDescription = createTestDescriptionFromScenario({ scenario: preparedScenario });
|
|
401
419
|
const testYamlContent = getYamlBytes(testDescription);
|
|
402
420
|
return this.runTesterStart(namespace, kubePath, kubeContext, clusterName, address, testYamlContent, false);
|
|
403
421
|
}
|
|
404
422
|
|
|
405
423
|
/**
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
async testerStartV1(
|
|
419
|
-
const
|
|
424
|
+
* Starts a test scenario in a specified namespace.
|
|
425
|
+
*
|
|
426
|
+
* @param {string|object} namespaceOrOptions - The namespace in which to start the test scenario or an options object.
|
|
427
|
+
* @param {string} [address] - The address of the target service to test.
|
|
428
|
+
* @param {object} [scenario] - The scenario object that defines the test steps and assertions.
|
|
429
|
+
* @param {string} [testName] - The name of the test.
|
|
430
|
+
* @param {object} [globalHeaders] - Optional global headers to be included in the test requests.
|
|
431
|
+
* @param {boolean} [generateTestReport] - Optional flag to generate a test report. Default is false.
|
|
432
|
+
* @param {boolean} [isDockerenv] - Optional flag to indicate if the test is running in a Docker environment. Default is false.
|
|
433
|
+
*
|
|
434
|
+
* @returns {Promise} - A promise that resolves when the test scenario is started.
|
|
435
|
+
*/
|
|
436
|
+
async testerStartV1(options = {}) {
|
|
437
|
+
const {
|
|
438
|
+
namespace = "",
|
|
439
|
+
address = "",
|
|
440
|
+
scenario,
|
|
441
|
+
testName,
|
|
442
|
+
globalHeaders = null,
|
|
443
|
+
generateTestReport = false,
|
|
444
|
+
isDockerenv = false,
|
|
445
|
+
kubePath = "",
|
|
446
|
+
kubeContext = "",
|
|
447
|
+
clusterName = ""
|
|
448
|
+
} = typeof options === 'object' ? options : {
|
|
449
|
+
namespace: options,
|
|
450
|
+
address: arguments[1],
|
|
451
|
+
scenario: arguments[2],
|
|
452
|
+
testName: arguments[3],
|
|
453
|
+
globalHeaders: arguments[4] || null,
|
|
454
|
+
generateTestReport: arguments[5] || false,
|
|
455
|
+
isDockerenv: arguments[6] || false
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
const scenarioToUse = scenario || this.scenario;
|
|
459
|
+
const preparedScenario = scenarioToUse ? scenarioToUse.prepareTestDescription() : null;
|
|
460
|
+
|
|
461
|
+
const testDescription = createTestDescriptionFromScenario({ ...options, scenario: preparedScenario });
|
|
420
462
|
const testYamlContent = getYamlBytes(testDescription);
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
463
|
+
const stringifiedHeaders = JSON.stringify(globalHeaders);
|
|
464
|
+
|
|
465
|
+
return this.runTesterStartv1( namespace,
|
|
466
|
+
kubePath,
|
|
467
|
+
kubeContext,
|
|
468
|
+
clusterName,
|
|
469
|
+
address,
|
|
470
|
+
testYamlContent,
|
|
471
|
+
testName,
|
|
472
|
+
stringifiedHeaders,
|
|
473
|
+
generateTestReport,
|
|
474
|
+
isDockerenv
|
|
475
|
+
);
|
|
425
476
|
}
|
|
426
477
|
|
|
427
478
|
// NPM only: for VS code extension use
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Scenario from './Scenario';
|
|
2
|
+
import Asserts from './Asserts';
|
|
3
|
+
import RequestValue from './RequestValue';
|
|
4
|
+
|
|
5
|
+
export interface StepConfig {
|
|
6
|
+
stepName: string;
|
|
7
|
+
maxRetries?: number;
|
|
8
|
+
interval?: string;
|
|
9
|
+
until?: string;
|
|
10
|
+
blobOverride?: {[blobName: string]: string};
|
|
11
|
+
override?: {[varName: string]: string | number};
|
|
12
|
+
description?: string;
|
|
13
|
+
break?: boolean;
|
|
14
|
+
ignore?: boolean;
|
|
15
|
+
if_?: string;
|
|
16
|
+
export?: {[exportName: string]: string | number};
|
|
17
|
+
untilFunc?: CallableFunction;
|
|
18
|
+
wait?: string;
|
|
19
|
+
with_?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface StepOptions extends StepConfig {
|
|
23
|
+
step: Scenario | Asserts | RequestValue;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export declare class Step {
|
|
27
|
+
constructor(options: StepOptions);
|
|
28
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
|
|
2
|
+
const RequestValue = require('./RequestValue');
|
|
3
|
+
const Asserts = require('./Asserts');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents a step in a scenario.
|
|
7
|
+
* @class
|
|
8
|
+
*/
|
|
9
|
+
class Step {
|
|
10
|
+
/**
|
|
11
|
+
* Initialize a new instance of a Step.
|
|
12
|
+
* @constructor
|
|
13
|
+
* @param {Object} options - The options for initializing the Step object.
|
|
14
|
+
* @param {Object} options.step - The step object, which can be an instance of RequestValue, Asserts, or Scenario.
|
|
15
|
+
* @param {number} [options.maxRetries=0] - The maximum number of retries for the step.
|
|
16
|
+
* @param {number} [options.interval] - The interval between retries.
|
|
17
|
+
* @param {string} [options.until] - The condition to wait until.
|
|
18
|
+
* @param {Object} [options.blobOverride] - The blob override for the step.
|
|
19
|
+
* @param {Object} [options.override] - The override for the step.
|
|
20
|
+
* @param {string} [options.description] - The description of the step.
|
|
21
|
+
* @param {string} [options.stepName] - The name of the step.
|
|
22
|
+
* @param {boolean} [options.break] - Whether to break the step.
|
|
23
|
+
* @param {boolean} [options.ignore] - Whether to ignore the step.
|
|
24
|
+
* @param {boolean} [options.if_] - The condition to check before executing the step.
|
|
25
|
+
* @param {boolean} [options.export] - Whether to export the step.
|
|
26
|
+
* @param {Function} [options.untilFunc] - The function to call until the condition is met.
|
|
27
|
+
* @param {number} [options.wait] - The wait time for the step.
|
|
28
|
+
* @param {Object} [options.with_] - Additional options for the step.
|
|
29
|
+
*/
|
|
30
|
+
constructor(options) {
|
|
31
|
+
const { step,
|
|
32
|
+
maxRetries,
|
|
33
|
+
interval,
|
|
34
|
+
until,
|
|
35
|
+
blobOverride,
|
|
36
|
+
override,
|
|
37
|
+
description,
|
|
38
|
+
stepName,
|
|
39
|
+
break: breakStep,
|
|
40
|
+
ignore,
|
|
41
|
+
if_,
|
|
42
|
+
export: exportStep,
|
|
43
|
+
untilFunc,
|
|
44
|
+
wait,
|
|
45
|
+
with_ } = options;
|
|
46
|
+
this.step = step;
|
|
47
|
+
this.maxRetries = maxRetries;
|
|
48
|
+
if (interval) this.interval = interval;
|
|
49
|
+
if (until) this.until = until;
|
|
50
|
+
if (blobOverride) this.blobOverride = blobOverride;
|
|
51
|
+
if (override) this.override = override;
|
|
52
|
+
this.description = description;
|
|
53
|
+
this.stepName = stepName;
|
|
54
|
+
if (breakStep) this.break = breakStep;
|
|
55
|
+
if (ignore) this.ignore = ignore;
|
|
56
|
+
if (if_) this.if = if_;
|
|
57
|
+
if (exportStep) this.export = exportStep;
|
|
58
|
+
if (untilFunc) this.untilFunc = untilFunc;
|
|
59
|
+
if (wait) this.wait = wait;
|
|
60
|
+
if (with_) this.with = with_;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getRepeatConfig() {
|
|
64
|
+
return {
|
|
65
|
+
...(this.maxRetries !== undefined && { maxRetries: this.maxRetries }),
|
|
66
|
+
...(this.interval !== undefined && { interval: this.interval }),
|
|
67
|
+
...(this.until !== undefined && { until: this.until }),
|
|
68
|
+
...(this.untilFunc !== undefined && { untilFunc: this.untilFunc }),
|
|
69
|
+
...(this.with !== undefined && { with: this.with }),
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Convert the step to a JSON object.
|
|
74
|
+
* @returns {Object} The JSON representation of the step.
|
|
75
|
+
*/
|
|
76
|
+
toJson() {
|
|
77
|
+
const step = {};
|
|
78
|
+
try {
|
|
79
|
+
if (this.step instanceof RequestValue) {
|
|
80
|
+
step.requestName = this.step.name;
|
|
81
|
+
} else if (this.step instanceof Asserts) {
|
|
82
|
+
step.asserts = this.step.toAssert();
|
|
83
|
+
} else {
|
|
84
|
+
if (this.step && this.step.constructor && this.step.constructor.name === 'Scenario') {
|
|
85
|
+
step.scenarioName = this.step.name;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error(error);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const additional = {
|
|
93
|
+
description: this.description,
|
|
94
|
+
name: this.stepName,
|
|
95
|
+
...(this.blobOverride !== undefined && { blobOverride: this.blobOverride }),
|
|
96
|
+
...(this.break !== undefined && { break: this.break }),
|
|
97
|
+
...(this.export !== undefined && { export: this.export }),
|
|
98
|
+
...(this.if !== undefined && { if: this.if }),
|
|
99
|
+
...(this.ignore !== undefined && { ignore: this.ignore }),
|
|
100
|
+
...(this.override !== undefined && { override: this.override }),
|
|
101
|
+
...(this.untilFunc !== undefined && { untilFunc: this.untilFunc }),
|
|
102
|
+
...(this.wait !== undefined && { wait: this.wait }),
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
...step,
|
|
107
|
+
...additional,
|
|
108
|
+
...(this.maxRetries !== undefined && { repeat: this.getRepeatConfig() }),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = Step;
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -8,6 +8,8 @@ const RestParam = require('./classes/RestParam');
|
|
|
8
8
|
const TrafficConfig = require('./classes/TrafficConfig');
|
|
9
9
|
const DelayConfig = require('./classes/DelayConfig');
|
|
10
10
|
const Protocol = require('./classes/Protocol');
|
|
11
|
+
const Asserts= require('./classes/Asserts');
|
|
12
|
+
const Step = require('./classes/Step');
|
|
11
13
|
|
|
12
14
|
module.exports = {
|
|
13
15
|
SkyrampClient,
|
|
@@ -20,4 +22,6 @@ module.exports = {
|
|
|
20
22
|
TrafficConfig,
|
|
21
23
|
DelayConfig,
|
|
22
24
|
Protocol,
|
|
25
|
+
Asserts,
|
|
26
|
+
Step
|
|
23
27
|
}
|
package/src/utils.js
CHANGED
|
@@ -12,23 +12,24 @@ function getYamlBytes(jsonObject) {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
function createTestDescriptionFromScenario(scenario) {
|
|
16
|
-
|
|
15
|
+
function createTestDescriptionFromScenario({ scenario, globalVars }) {
|
|
16
|
+
const { name, startsAt = 1, scenarios, services, endpoints, requests } = scenario;
|
|
17
|
+
const testDescription = {
|
|
17
18
|
version: SKYRAMP_YAML_VERSION,
|
|
18
19
|
test: {
|
|
20
|
+
...(globalVars !== undefined && { globalVars }),
|
|
19
21
|
testPattern: [{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
startAt: startsAt,
|
|
23
|
+
scenarioName: name
|
|
22
24
|
}]
|
|
23
25
|
},
|
|
24
|
-
services:
|
|
25
|
-
endpoints:
|
|
26
|
-
scenarios:
|
|
27
|
-
|
|
28
|
-
steps: scenario.steps
|
|
29
|
-
}],
|
|
30
|
-
requests: scenario.requests
|
|
26
|
+
services: services,
|
|
27
|
+
endpoints: endpoints,
|
|
28
|
+
scenarios: scenarios,
|
|
29
|
+
requests: requests
|
|
31
30
|
};
|
|
31
|
+
|
|
32
|
+
return testDescription;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
function readDataFromFile(filename) {
|