@skyramp/skyramp 1.0.0-sha.b2dfe11 → 1.2.2
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/LICENSE +21 -0
- package/README.md +10 -17
- package/package.json +14 -5
- package/scripts/download-binary.js +189 -0
- package/src/classes/Asserts.d.ts +16 -0
- package/src/classes/Asserts.js +41 -0
- package/src/classes/AsyncScenario.d.ts +133 -0
- package/src/classes/AsyncScenario.js +324 -0
- package/src/classes/AsyncTestStatus.d.ts +172 -0
- package/src/classes/AsyncTestStatus.js +488 -0
- package/src/classes/DelayConfig.d.ts +4 -0
- package/src/classes/DelayConfig.js +25 -0
- package/src/classes/Endpoint.d.ts +2 -2
- package/src/classes/Endpoint.js +81 -43
- package/src/classes/GrpcEndpoint.d.ts +1 -1
- package/src/classes/GrpcEndpoint.js +24 -3
- package/src/classes/LoadTestConfig.d.ts +131 -0
- package/src/classes/LoadTestConfig.js +186 -0
- package/src/classes/Protocol.d.ts +5 -0
- package/src/classes/Protocol.js +8 -0
- package/src/classes/RequestV2.d.ts +30 -0
- package/src/classes/RequestV2.js +181 -0
- package/src/classes/RequestValue.d.ts +24 -0
- package/src/classes/RequestValue.js +113 -0
- package/src/classes/ResponseV2.d.ts +24 -0
- package/src/classes/ResponseV2.js +96 -0
- package/src/classes/ResponseValue.d.ts +21 -0
- package/src/classes/ResponseValue.js +93 -0
- package/src/classes/RestEndpoint.d.ts +11 -2
- package/src/classes/RestEndpoint.js +90 -5
- package/src/classes/RestParam.d.ts +4 -0
- package/src/classes/RestParam.js +32 -0
- package/src/classes/Scenario.d.ts +48 -0
- package/src/classes/Scenario.js +208 -0
- package/src/classes/SkyrampClient.d.ts +184 -4
- package/src/classes/SkyrampClient.js +774 -40
- package/src/classes/Step.d.ts +28 -0
- package/src/classes/Step.js +113 -0
- package/src/classes/TrafficConfig.d.ts +6 -0
- package/src/classes/TrafficConfig.js +28 -0
- package/src/function.js +46 -0
- package/src/index.d.ts +14 -1
- package/src/index.js +36 -3
- package/src/lib.js +6 -6
- package/src/utils.js +180 -20
- package/src/utils.d.ts +0 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Skyramp
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# skyramp
|
|
2
|
+
|
|
3
|
+
`skyramp` is an npm module that provides functionalities to generate and execute a variety of functional tests (including smoke, contract, and integration tests). It also offers features for asserting scenarios in various test environments.
|
|
4
|
+
|
|
5
|
+
For more information about Skyramp, please visit [our website](https://skyramp.dev).
|
|
3
6
|
|
|
4
7
|
## Installation
|
|
5
|
-
To install Skyramp,
|
|
6
|
-
```
|
|
7
|
-
npm install skyramp
|
|
8
|
-
```
|
|
8
|
+
To install Skyramp, please refer to the [installation instructions](https://skyramp.dev/docs/quickstart/install) to set up the Skyramp CLI as well as the required dependencies.
|
|
9
9
|
|
|
10
10
|
## Usage
|
|
11
|
-
Once you
|
|
11
|
+
To use `skyramp` please refer to the guide to [generate your first test](https:skyramp.dev/docs/quickstart/first-test-general). Once you generate your first integration test in TypeScript using the Skyramp CLI, you can execute the test with the following command:
|
|
12
12
|
|
|
13
|
+
```bash
|
|
14
|
+
npx playwright test products_integration_test.spec.ts --reporter=list
|
|
13
15
|
```
|
|
14
|
-
const skyramp = require('skyramp');
|
|
15
|
-
```
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
- `runConfigApplyLocal`: create a new local test cluster
|
|
19
|
-
- `runAddKubeconfig`: specify kubeconfig for a pre-provisioned workload cluster
|
|
20
|
-
- `runConfigRemoveLocal`: remove a local test cluster
|
|
21
|
-
- `runConfigRemove`: remove a test cluster
|
|
22
|
-
- `runMockerCreate`: generate Mocker configurations
|
|
23
|
-
- `runMockerDeploy`: update Mocker configurations and source schema files
|
|
24
|
-
- `runTesterStart`: starts a skyramp test specified in the test description file
|
|
17
|
+
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skyramp/skyramp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "module for leveraging skyramp cli functionality",
|
|
5
5
|
"scripts": {
|
|
6
|
+
"lint": "eslint 'src/**/*.js' 'src/**/*.ts' --fix",
|
|
6
7
|
"pack": "npm pack",
|
|
7
|
-
"
|
|
8
|
+
"reference-docs": "documentation build src/**/*.js src/classes/**/*.js -f md -o reference.md",
|
|
9
|
+
"postinstall": "node scripts/download-binary.js",
|
|
10
|
+
"clean": "rimraf node_modules && rimraf package-lock.json && rimraf skyramp && rimraf lib/*"
|
|
8
11
|
},
|
|
9
12
|
"files": [
|
|
10
|
-
"
|
|
13
|
+
"scripts/*.js",
|
|
11
14
|
"src/*.js",
|
|
12
15
|
"src/*.ts",
|
|
13
16
|
"src/classes/*.js",
|
|
@@ -15,10 +18,16 @@
|
|
|
15
18
|
],
|
|
16
19
|
"main": "src/index.js",
|
|
17
20
|
"author": "",
|
|
18
|
-
"license": "
|
|
21
|
+
"license": "MIT",
|
|
19
22
|
"dependencies": {
|
|
23
|
+
"@aws-sdk/client-s3": "^3.812.0",
|
|
20
24
|
"fs": "^0.0.1-security",
|
|
21
25
|
"js-yaml": "^4.1.0",
|
|
22
|
-
"koffi": "
|
|
26
|
+
"koffi": "2.5.12"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
|
30
|
+
"@typescript-eslint/parser": "^6.14.0",
|
|
31
|
+
"eslint": "^8.55.0"
|
|
23
32
|
}
|
|
24
33
|
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
const https = require('https');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const crypto = require('crypto');
|
|
5
|
+
const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
|
|
6
|
+
|
|
7
|
+
function log(level, message) {
|
|
8
|
+
const timestamp = new Date().toISOString();
|
|
9
|
+
console.log(`[${timestamp}] [${level.toUpperCase()}] ${message}`);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let S3_PRIVATE = process.env.S3_PRIVATE || false; // Set to true if libraries are in a private S3 bucket
|
|
13
|
+
const AWS_REGION = process.env.AWS_REGION || 'us-west-2'; // Set your AWS region
|
|
14
|
+
const SKIP_DOWNLOAD = process.env.SKIP_DOWNLOAD || false; // Set to true to skip the download process
|
|
15
|
+
const PUBLIC_BUCKET_NAME = process.env.INT_LIBRARY_BUCKET || 'skyramp-public'; // Set to your S3 public bucket name
|
|
16
|
+
const PUBLIC_LIBRARY_PATH = process.env.INT_LIBRARY_PATH || `release/v${require('../package.json').version}/lib`; // Set to your S3 public library root path
|
|
17
|
+
const PRIVATE_BUCKET_NAME = process.env.INT_LIBRARY_BUCKET || undefined; // Set to your S3 private bucket name
|
|
18
|
+
const PRIVATE_LIBRARY_PATH = process.env.INT_LIBRARY_PATH || ''; // Set to your S3 private library root path
|
|
19
|
+
|
|
20
|
+
if (SKIP_DOWNLOAD) {
|
|
21
|
+
log('info', "Skipping download as requested by SKIP_DOWNLOAD=true.");
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (process.env.CI) {
|
|
26
|
+
log('info', "Running in CI environment. Defaulting to private S3 download.");
|
|
27
|
+
S3_PRIVATE = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const archMap = {
|
|
31
|
+
x64: 'amd64',
|
|
32
|
+
ia32: '386',
|
|
33
|
+
arm: 'arm',
|
|
34
|
+
arm64: 'arm64',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const platformMap = {
|
|
38
|
+
win32: 'windows',
|
|
39
|
+
darwin: 'darwin',
|
|
40
|
+
linux: 'linux',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const extMap = {
|
|
44
|
+
windows: 'dll',
|
|
45
|
+
darwin: 'dylib',
|
|
46
|
+
linux: 'so',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const rawPlatform = process.platform;
|
|
50
|
+
const rawArch = process.arch;
|
|
51
|
+
const platform = platformMap[rawPlatform];
|
|
52
|
+
const arch = archMap[rawArch];
|
|
53
|
+
const ext = extMap[platform];
|
|
54
|
+
|
|
55
|
+
if (!platform || !arch || !ext) {
|
|
56
|
+
log('error', `Unsupported platform or architecture: ${rawPlatform} / ${rawArch}`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const prefix = 'skyramp';
|
|
61
|
+
const binaryFilename = `${prefix}-${platform}-${arch}.${ext}`;
|
|
62
|
+
const headerFilename = `${prefix}-${platform}-${arch}.h`;
|
|
63
|
+
|
|
64
|
+
const baseUrl = `https://${PUBLIC_BUCKET_NAME}.s3.${AWS_REGION}.amazonaws.com/${PUBLIC_LIBRARY_PATH}/`;
|
|
65
|
+
const localDir = path.join(__dirname, '..', 'lib');
|
|
66
|
+
|
|
67
|
+
const files = [
|
|
68
|
+
{ name: binaryFilename, dest: path.join(localDir, binaryFilename) },
|
|
69
|
+
{ name: headerFilename, dest: path.join(localDir, headerFilename) },
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
async function calculateMD5(filePath) {
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
const hash = crypto.createHash('md5');
|
|
75
|
+
const stream = fs.createReadStream(filePath);
|
|
76
|
+
stream.on('data', data => hash.update(data));
|
|
77
|
+
stream.on('end', () => resolve(hash.digest('hex')));
|
|
78
|
+
stream.on('error', (err) => {
|
|
79
|
+
log('error', `Failed to calculate MD5 for ${filePath}: ${err.message}`);
|
|
80
|
+
reject(err);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function getETag(url) {
|
|
86
|
+
return new Promise((resolve, reject) => {
|
|
87
|
+
https.get(url, { method: 'HEAD' }, res => {
|
|
88
|
+
if (res.statusCode !== 200) {
|
|
89
|
+
reject(new Error(`HTTP ${res.statusCode}: ${url}`));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
resolve(res.headers['etag']?.replace(/"/g, '')); // Remove quotes from ETag
|
|
93
|
+
}).on('error', (err) => {
|
|
94
|
+
log('error', `Error during HEAD request to ${url}: ${err.message}`);
|
|
95
|
+
reject(err);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function download(url, dest, options = {}) {
|
|
101
|
+
await fs.promises.mkdir(path.dirname(dest), { recursive: true });
|
|
102
|
+
|
|
103
|
+
const { session, bucket, s3Key } = options;
|
|
104
|
+
|
|
105
|
+
return new Promise((resolve, reject) => {
|
|
106
|
+
if (session && bucket && s3Key) {
|
|
107
|
+
// Private S3 download using AWS SDK
|
|
108
|
+
const command = new GetObjectCommand({ Bucket: bucket, Key: s3Key });
|
|
109
|
+
session.send(command).then(response => {
|
|
110
|
+
const stream = response.Body;
|
|
111
|
+
const file = fs.createWriteStream(dest);
|
|
112
|
+
stream.pipe(file);
|
|
113
|
+
stream.on('error', (err) => {
|
|
114
|
+
log('error', `Error streaming file from S3: ${err.message}`);
|
|
115
|
+
reject(err);
|
|
116
|
+
});
|
|
117
|
+
file.on('finish', () => {
|
|
118
|
+
log('info', `Successfully downloaded ${s3Key} to ${dest}`);
|
|
119
|
+
file.close(resolve);
|
|
120
|
+
});
|
|
121
|
+
}).catch(err => {
|
|
122
|
+
log('error', `Failed to download ${s3Key} from S3: ${err.message}`);
|
|
123
|
+
reject(err);
|
|
124
|
+
});
|
|
125
|
+
} else {
|
|
126
|
+
// Public URL download using https
|
|
127
|
+
https.get(url, res => {
|
|
128
|
+
if (res.statusCode !== 200) {
|
|
129
|
+
const error = new Error(`HTTP ${res.statusCode}: ${url}`);
|
|
130
|
+
log('error', `Failed to download ${url}: ${error.message}`);
|
|
131
|
+
reject(error);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const file = fs.createWriteStream(dest);
|
|
135
|
+
res.pipe(file);
|
|
136
|
+
file.on('finish', () => {
|
|
137
|
+
log('info', `Successfully downloaded ${url} to ${dest}`);
|
|
138
|
+
file.close(resolve);
|
|
139
|
+
});
|
|
140
|
+
}).on('error', (err) => {
|
|
141
|
+
log('error', `Error during download from ${url}: ${err.message}`);
|
|
142
|
+
reject(err);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
(async () => {
|
|
149
|
+
for (const file of files) {
|
|
150
|
+
let options = {};
|
|
151
|
+
let url = baseUrl + file.name;
|
|
152
|
+
const localFile = file.dest;
|
|
153
|
+
log('info', `Processing ${file.name}...`);
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
if (S3_PRIVATE) {
|
|
157
|
+
log("Pulling libraries from Private S3.");
|
|
158
|
+
const s3 = new S3Client({region: AWS_REGION});
|
|
159
|
+
|
|
160
|
+
url = null; // No URL needed for S3 private download client
|
|
161
|
+
options = {
|
|
162
|
+
session: s3,
|
|
163
|
+
bucket: PRIVATE_BUCKET_NAME,
|
|
164
|
+
s3Key: `${PRIVATE_LIBRARY_PATH}/${file.name}`
|
|
165
|
+
};
|
|
166
|
+
} else if (fs.existsSync(localFile)) {
|
|
167
|
+
log('info', `Checking ${file.name} for changes...`);
|
|
168
|
+
const remoteETag = await getETag(url);
|
|
169
|
+
const localHash = await calculateMD5(localFile);
|
|
170
|
+
log('debug', `Remote ETag: ${remoteETag}, Local Hash: ${localHash}`);
|
|
171
|
+
|
|
172
|
+
if (remoteETag === localHash) {
|
|
173
|
+
log('info', `✅ ${file.name} is up-to-date.`);
|
|
174
|
+
continue;
|
|
175
|
+
} else {
|
|
176
|
+
log('info', `🔄 ${file.name} differs, downloading...`);
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
log('info', `⬇️ ${file.name} not found locally, downloading...`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
await download(url, file.dest, options);
|
|
183
|
+
log('info', `✅ Saved ${file.name} to ${file.dest}`);
|
|
184
|
+
} catch (e) {
|
|
185
|
+
log('error', `❌ Failed to process ${file.name}: ${e.message}`);
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
})();
|
|
@@ -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;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { RequestV2 } from "./RequestV2";
|
|
2
|
+
|
|
3
|
+
export interface AsyncRequestOptions {
|
|
4
|
+
name?: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
path?: string;
|
|
7
|
+
method?: string;
|
|
8
|
+
body?: string;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
pathParams?: Record<string, string>;
|
|
11
|
+
queryParams?: Record<string, string | number | boolean>;
|
|
12
|
+
formParams?: Record<string, string | number | boolean>;
|
|
13
|
+
multipartParams?: Record<string, string | number | boolean>;
|
|
14
|
+
dataOverride?: Record<string, string | number | boolean>;
|
|
15
|
+
description?: string;
|
|
16
|
+
expectedCode?: string;
|
|
17
|
+
if_?: string;
|
|
18
|
+
until?: string;
|
|
19
|
+
maxRetries?: number;
|
|
20
|
+
retryInterval?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class AsyncRequest {
|
|
24
|
+
scenario: AsyncScenario;
|
|
25
|
+
request: RequestV2;
|
|
26
|
+
stepIndex: number;
|
|
27
|
+
|
|
28
|
+
constructor(scenario: AsyncScenario, request: RequestV2, stepIndex: number);
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns request's response value construct for asynchronous backend
|
|
32
|
+
* @param path The path to the value
|
|
33
|
+
*/
|
|
34
|
+
getAsyncRequestValue(path: string | null): string;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns request's status check construct for asynchronous backend
|
|
38
|
+
* @param code The expected status code
|
|
39
|
+
*/
|
|
40
|
+
requestStatusCheck(code: string | number): string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Adds an assert to the request
|
|
44
|
+
* @param jsonPath The JSON path to the value
|
|
45
|
+
* @param expectedValue The expected value
|
|
46
|
+
*/
|
|
47
|
+
assertEqual(jsonPath: string, expectedValue: string | number | boolean): void;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Adds a not equal assert to the request
|
|
51
|
+
* @param jsonPath The JSON path to the value
|
|
52
|
+
* @param value The value to compare against
|
|
53
|
+
*/
|
|
54
|
+
assertNotEqual(jsonPath: string, value: string | number | boolean): void;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface AsyncScenarioOptions {
|
|
58
|
+
name: string;
|
|
59
|
+
ignoreFailure?: boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class AsyncScenario {
|
|
63
|
+
name: string;
|
|
64
|
+
steps: AsyncRequest[];
|
|
65
|
+
vars: Record<string, string | number | boolean>;
|
|
66
|
+
until: string;
|
|
67
|
+
maxRetries: number;
|
|
68
|
+
retryInterval: number;
|
|
69
|
+
ignoreFailure: boolean;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Creates a new AsyncScenario
|
|
73
|
+
* @param options The scenario options
|
|
74
|
+
*/
|
|
75
|
+
constructor(options: AsyncScenarioOptions);
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Adds an asynchronous request to this scenario
|
|
79
|
+
* @param options The request options
|
|
80
|
+
*/
|
|
81
|
+
addAsyncRequest(options?: AsyncRequestOptions): AsyncRequest;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Adds an asynchronous nested scenario to this scenario
|
|
85
|
+
* @param nestedScenario The nested scenario to add
|
|
86
|
+
* @param until The condition to stop retrying
|
|
87
|
+
* @param maxRetries The maximum number of retries
|
|
88
|
+
* @param retryInterval The interval between retries
|
|
89
|
+
*/
|
|
90
|
+
addAsyncScenario(
|
|
91
|
+
nestedScenario: AsyncScenario,
|
|
92
|
+
until?: string,
|
|
93
|
+
maxRetries?: number,
|
|
94
|
+
retryInterval?: number
|
|
95
|
+
): void;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Sets a scenario level variable
|
|
99
|
+
* @param varName The name of the variable
|
|
100
|
+
* @param value The value of the variable
|
|
101
|
+
*/
|
|
102
|
+
setAsyncVar(varName: string, value: string | number | boolean): void;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Returns scenario's variable construct for asynchronous backend
|
|
106
|
+
* @param varName The name of the variable
|
|
107
|
+
*/
|
|
108
|
+
getAsyncVar(varName: string): string;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Returns scenario's response value construct for asynchronous backend
|
|
112
|
+
* @param varName The name of the variable
|
|
113
|
+
*/
|
|
114
|
+
getAsyncScenarioValue(varName: string): string;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Sets a scenario level variable for export
|
|
118
|
+
* @param varName The name of the variable
|
|
119
|
+
* @param value The value of the variable
|
|
120
|
+
*/
|
|
121
|
+
exportAsyncVar(varName: string, value: string | number | boolean): void;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Adds an assert to the scenario
|
|
125
|
+
* @param value The value to assert
|
|
126
|
+
*/
|
|
127
|
+
addAssert(value: string): void;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Converts this scenario to JSON
|
|
131
|
+
*/
|
|
132
|
+
toJson(): Record<string, string | number | boolean | object | null>;
|
|
133
|
+
}
|