@skyramp/skyramp 0.4.91 → 0.4.93

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.
Binary file
@@ -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
@@ -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);
@@ -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
@@ -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
Binary file
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyramp/skyramp",
3
- "version": "0.4.91",
3
+ "version": "0.4.93",
4
4
  "description": "module for leveraging skyramp cli functionality",
5
5
  "scripts": {
6
6
  "lint": "eslint 'src/**/*.js' 'src/**/*.ts' --fix",
@@ -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(name, service, port, pbFile, endpointAddress) {
20
- const response = newGrpcEndpointWrapper(name, service, port, pbFile, endpointAddress);
21
- super(response, endpointAddress);
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?: Map<string, string | number>;
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: RequestValue)
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
+ }
@@ -1,5 +1,8 @@
1
1
  const lib = require('../lib');
2
- const { createTestDescriptionFromScenario, getYamlBytes, readDataFromFile, SKYRAMP_YAML_VERSION } = require('../utils');
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(name) {
17
- this.name = name;
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 and updates the list of services and endpoints.
34
- * @param {Request} request - The request to add to the scenario.
35
- * @returns {string} - The name of the added request.
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(request) {
38
- this.steps.push({ requestName: request.name });
39
- this.requests.push(request.asRequestDict());
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
- if (!this.services.find(s => s === request.endpointDescriptor.services)) {
42
- this.services.push(request.endpointDescriptor.services[0]);
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 (!this.endpoints.find(ep => ep === request.endpointDescriptor.endpoint)) {
46
- this.endpoints.push(request.endpointDescriptor.endpoint);
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
- addRequest(endpoint, methodName, requestObject=undefined, dynamic=false) {
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 this.requests) {
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 (this.endpoints.indexOf(endpoint.endpoint) !== -1) {
149
+ if (Scenario.endpoints.indexOf(endpoint.endpoint) !== -1) {
76
150
  return;
77
151
  }
78
-
79
- this.services.push(...endpoint.services);
80
- this.endpoints.push(endpoint.endpoint);
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
- this.requests.push(requests[0]);
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(this);
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
- testerStartFromFile(namespace: string, kubePath: string, kubeContext: string, clusterName: string, address: string, filePath: string): Promise<void>;
29
- runTesterStart(namespace: string, kubePath: string, kubeContext: string, clusterName: string, address: string, testYamlContent: string, generateReport: boolean): Promise<void>;
30
- initTarget(targetName: string): Promise<void>;
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(namespace, kubeConfig, kubeContext, clusterName, address, response, trafficConfig) {
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 testDescription = createTestDescriptionFromScenario(scenario);
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
- * Starts a test scenario in a specified namespace.
407
- *
408
- * @param {string} namespace - The namespace in which to start the test scenario.
409
- * @param {string} address - The address of the target service to test.
410
- * @param {object} scenario - The scenario object that defines the test steps and assertions.
411
- * @param {string} testName - The name of the test.
412
- * @param {object} globalHeaders - Optional global headers to be included in the test requests.
413
- * @param {boolean} generateTestReport - Optional flag to generate a test report. Default is false.
414
- * @param {boolean} isDockerenv - Optional flag to indicate if the test is running in a Docker environment. Default is false.
415
- *
416
- * @returns {Promise} - A promise that resolves when the test scenario is started.
417
- */
418
- async testerStartV1(namespace, address, scenario, testName, globalHeaders, generateTestReport = false) {
419
- const testDescription = createTestDescriptionFromScenario(scenario);
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
- if (globalHeaders !== undefined && globalHeaders !== null) {
422
- globalHeaders = JSON.stringify(globalHeaders);
423
- }
424
- return this.runTesterStartv1(namespace, '', '', '', address, testYamlContent, testName, globalHeaders, generateTestReport);
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
@@ -8,4 +8,4 @@ export * from './classes/ResponseValue';
8
8
  export * from './classes/RestParam';
9
9
  export * from './classes/TrafficConfig';
10
10
  export * from './classes/DelayConfig';
11
- export * from './classes/Protocol';
11
+ export * from './classes/Protocol';
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
- return {
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
- startAt: 1,
21
- scenarioName: scenario.name
22
+ startAt: startsAt,
23
+ scenarioName: name
22
24
  }]
23
25
  },
24
- services: scenario.services,
25
- endpoints: scenario.endpoints,
26
- scenarios: [{
27
- name: scenario.name,
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) {