Update readme and small bug fix (#644)
* fix lint * add gif * add installOav.gif * update oav -h in readme * update runApiTest doc * small fix * avoid conflict step name when generate postman collection item * update changelog * support verbose command update gif * update doc * refine doc * poller do not output err * update gif * fix typo * bug fix. setup subscriptionId as environment variables * update changelog
This commit is contained in:
Родитель
8e43493bf9
Коммит
5660d08093
|
@ -5,6 +5,10 @@
|
|||
- Oav runner support specifying option 'runId' with option 'from' and/or 'to' to debug.
|
||||
- Oav runner support using env variable 'TEST_SCENARIO_JSON_ENV' to override variables in env.json.
|
||||
- Replace Oav runner option 'cleanUp' with 'skipCleanUp'.
|
||||
- Update README.md add gif to show API test
|
||||
- Fix bug. Avoid duplicate step name when generate postman collection
|
||||
- Small bug fix. Set postman collection subscriptionId env when do AAD auth
|
||||
- Response diff ignore exception
|
||||
|
||||
## 07/15/2021 2.6.2
|
||||
|
||||
|
@ -25,7 +29,6 @@
|
|||
|
||||
## 07/05/2021 2.5.9
|
||||
|
||||
|
||||
- Ignore LRO_RESPONSE_HEADER rule check in case of synchronous api call
|
||||
|
||||
## 06/25/2021 2.5.8
|
||||
|
|
80
README.md
80
README.md
|
@ -3,7 +3,6 @@
|
|||
[![Build Status](https://dev.azure.com/azure-public/adx/_apis/build/status/public.Azure.oav)](https://dev.azure.com/azure-public/adx/_build/latest?definitionId=3)
|
||||
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
|
||||
|
||||
|
||||
Regression: [![Build Status](https://dev.azure.com/azure-sdk/public/_apis/build/status/OAV%20Validate%20Examples%20Regression?branchName=master)](https://dev.azure.com/azure-sdk/public/_build/latest?definitionId=163&branchName=master) [How to fix this](#fixing-regression-builds)
|
||||
|
||||
Tools for validating OpenAPI (Swagger) files.
|
||||
|
@ -17,17 +16,39 @@ You can install the latest stable release of node.js from [here](https://nodejs.
|
|||
### How to install the tool
|
||||
|
||||
```bash
|
||||
npm install -g oav
|
||||
npm install -g oav@latest
|
||||
```
|
||||
|
||||
![](./documentation/installOav.gif)
|
||||
|
||||
### Run API test
|
||||
|
||||
OAV support run API test against Azure and validate request and response. You could define test scenario file which compose with severval swagger example file and then use oav to run it. For more details about API test, please refer to this [API testing doc](https://github.com/Azure/azure-rest-api-specs/tree/test-scenario-main/documentation/test-scenario).
|
||||
|
||||
![](./documentation/runApiTest.gif)
|
||||
|
||||
#### Command usage:
|
||||
|
||||
```bash
|
||||
bash-3.2$ oav -h
|
||||
Commands:
|
||||
$ oav -h Commands:
|
||||
analyze-dependency analyze swagger resource type
|
||||
dependency.
|
||||
analyze-report <newman-report-path> analyze report. default format:
|
||||
newman json report
|
||||
example-quality <spec-path> Performs example quality validation
|
||||
of x-ms-examples and examples
|
||||
present in the spec.
|
||||
extract-xmsexamples <spec-path> Extracts the x-ms-examples for a
|
||||
<recordings> given swagger from the .NET session
|
||||
recordings and saves them in a file.
|
||||
generate-collection Generate postman collection file
|
||||
from test scenario.
|
||||
generate-examples [spec-path] Generate swagger examples from real
|
||||
payload records.
|
||||
generate-report [raw-report-path] Generate report from postman report.
|
||||
generate-test-scenario Generate swagger examples from real
|
||||
payload records.
|
||||
generate-static-test-scenario Generate test-scenario from swagger.
|
||||
generate-uml <spec-path> Generates a class diagram of the
|
||||
model definitions in the given
|
||||
swagger spec.
|
||||
|
@ -38,46 +59,45 @@ Commands:
|
|||
resolve-spec <spec-path> Resolves the swagger spec based on
|
||||
the selected options like allOfs,
|
||||
relativePaths, examples etc.
|
||||
run-test-scenario <test-scenario> newman runner run test scenario
|
||||
file. [aliases: run]
|
||||
validate-example <spec-path> Performs validation of x-ms-examples
|
||||
and examples present in the spec.
|
||||
validate-spec <spec-path> Performs semantic validation of the
|
||||
spec.
|
||||
validate-traffic <traffic-path> Validate traffic payload against
|
||||
<spec-path> the spec.
|
||||
validate-traffic <traffic-path> Validate traffic payload against the
|
||||
<spec-path> spec.
|
||||
|
||||
Options:
|
||||
--version Show version number [boolean]
|
||||
-l, --logLevel Set the logging level for console.
|
||||
[choices: "off", "json", "error", "warn", "info", "verbose", "debug", "silly"]
|
||||
[default: "warn"]
|
||||
[default: "info"]
|
||||
-f, --logFilepath Set the log file path. It must be an absolute filepath. By
|
||||
default the logs will stored in a timestamp based log file
|
||||
at "C:\Users\abc\oav_output".
|
||||
at "/home/ruowan/oav_output".
|
||||
-p, --pretty Pretty print
|
||||
-h, --help Show help [boolean]
|
||||
|
||||
bash-3.2$
|
||||
```
|
||||
|
||||
### What does the tool do? What issues does the tool catch?
|
||||
|
||||
- Semantic validation
|
||||
Semantic validation enforces correctness on the swagger specific elements. Such as paths and operations. Ensure the element definition meet the [OpenApi 2.0 specification](https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FOAI%2FOpenAPI-Specification%2Fblob%2Fmaster%2Fversions%2F2.0.md&data=02%7C01%7Craychen%40microsoft.com%7C8455b2c9dfe54f52d98c08d7cf1aad66%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637205585798284783&sdata=zZrZzk4emkODos7%2BqtMT4RG0ipuFiV7uC0lCWeYdRPE%3D&reserved=0).
|
||||
Semantic validation enforces correctness on the swagger specific elements. Such as paths and operations. Ensure the element definition meet the [OpenApi 2.0 specification](https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FOAI%2FOpenAPI-Specification%2Fblob%2Fmaster%2Fversions%2F2.0.md&data=02%7C01%7Craychen%40microsoft.com%7C8455b2c9dfe54f52d98c08d7cf1aad66%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637205585798284783&sdata=zZrZzk4emkODos7%2BqtMT4RG0ipuFiV7uC0lCWeYdRPE%3D&reserved=0).
|
||||
- Model validation
|
||||
Model validation enforces correctness between example and swagger. It checks whether definitions for request parameters and responses, match an expected input/output payload of the service.
|
||||
Examples of issues:
|
||||
- required properties not sent in requests or responses;
|
||||
- defined types not matching the value provided in the payload;
|
||||
- constraints on properties not met; enumeration values that don’t match the value used by the service.
|
||||
Model validation enforces correctness between example and swagger. It checks whether definitions for request parameters and responses, match an expected input/output payload of the service.
|
||||
Examples of issues: - required properties not sent in requests or responses; - defined types not matching the value provided in the payload; - constraints on properties not met; enumeration values that don’t match the value used by the service.
|
||||
|
||||
References: https://github.com/Azure/azure-rest-api-specs/issues/778 , https://github.com/Azure/azure-rest-api-specs/issues/755 , https://github.com/Azure/azure-rest-api-specs/issues/773
|
||||
|
||||
Model validation _requires_ example payloads (request/response) of the service, so the data can be matched with the defined models. See [x-ms-examples extension](https://github.com/Azure/azure-rest-api-specs/issues/648) on how to specify the examples/payloads. Swagger “examples” is also supported and data included there is validated as well. To get the most benefit from this tool, make sure to have the simplest and most complex examples possible as part of x-ms-examples.
|
||||
- Please take a look at the redis-cache swagger spec as an example for providing "x-ms-examples" over [here](https://github.com/Azure/azure-rest-api-specs/blob/master/arm-redis/2016-04-01/swagger/redis.json#L45).
|
||||
- The examples need to be provided in a separate file in the examples directory under the api-version directory `azure-rest-api-specs/arm-<yourService>/<api-version>/examples/<exampleName>.json`. You can take a look over [here](https://github.com/Azure/azure-rest-api-specs/tree/master/arm-redis/2016-04-01/examples) for the structure of examples.
|
||||
- We require you to provide us a minimum (just required properties/parameters of the request/response) and a maximum (full blown) example. Feel free to provide more examples as deemed necessary.
|
||||
- We have provided schemas for examples to be provided in the examples directory. It can be found over [here](https://github.com/Azure/autorest/blob/master/schema/example-schema.json). This will help you with intellisene and validation.
|
||||
- If you are using **vscode** to edit your swaggers in the azure-rest-api-specs repo then everything should work out of the box as the schemas have been added in the `.vscode/settings.json` file over [here](https://github.com/Azure/azure-rest-api-specs/blob/master/.vscode/settings.json).
|
||||
- If you are using **Visual Studio** then you can use the urls provided in the settings.json file and put them in the drop down list at the top of a json file when the file is opened in VS.
|
||||
References: https://github.com/Azure/azure-rest-api-specs/issues/778 , https://github.com/Azure/azure-rest-api-specs/issues/755 , https://github.com/Azure/azure-rest-api-specs/issues/773
|
||||
|
||||
Model validation _requires_ example payloads (request/response) of the service, so the data can be matched with the defined models. See [x-ms-examples extension](https://github.com/Azure/azure-rest-api-specs/issues/648) on how to specify the examples/payloads. Swagger “examples” is also supported and data included there is validated as well. To get the most benefit from this tool, make sure to have the simplest and most complex examples possible as part of x-ms-examples.
|
||||
- Please take a look at the redis-cache swagger spec as an example for providing "x-ms-examples" over [here](https://github.com/Azure/azure-rest-api-specs/blob/master/arm-redis/2016-04-01/swagger/redis.json#L45).
|
||||
- The examples need to be provided in a separate file in the examples directory under the api-version directory `azure-rest-api-specs/arm-<yourService>/<api-version>/examples/<exampleName>.json`. You can take a look over [here](https://github.com/Azure/azure-rest-api-specs/tree/master/arm-redis/2016-04-01/examples) for the structure of examples.
|
||||
- We require you to provide us a minimum (just required properties/parameters of the request/response) and a maximum (full blown) example. Feel free to provide more examples as deemed necessary.
|
||||
- We have provided schemas for examples to be provided in the examples directory. It can be found over [here](https://github.com/Azure/autorest/blob/master/schema/example-schema.json). This will help you with intellisene and validation.
|
||||
- If you are using **vscode** to edit your swaggers in the azure-rest-api-specs repo then everything should work out of the box as the schemas have been added in the `.vscode/settings.json` file over [here](https://github.com/Azure/azure-rest-api-specs/blob/master/.vscode/settings.json).
|
||||
- If you are using **Visual Studio** then you can use the urls provided in the settings.json file and put them in the drop down list at the top of a json file when the file is opened in VS.
|
||||
|
||||
### How does this tool fit with others
|
||||
|
||||
|
@ -116,19 +136,19 @@ pipeline:
|
|||
const liveValidatorOptions = {
|
||||
git: {
|
||||
url: "https://github.com/Azure/azure-rest-api-specs.git",
|
||||
shouldClone: true
|
||||
shouldClone: true,
|
||||
},
|
||||
directory: path.resolve(os.homedir(), "cloneRepo"),
|
||||
swaggerPathsPattern: "/specification/**/resource-manager/**/*.json",
|
||||
isPathCaseSensitive: false,
|
||||
shouldModelImplicitDefaultResponse: true
|
||||
}
|
||||
shouldModelImplicitDefaultResponse: true,
|
||||
};
|
||||
|
||||
const apiValidator = new oav.LiveValidator(liveValidatorOptions)
|
||||
await apiValidator.initialize() // Note that for a large number of specs this can take some time.
|
||||
const apiValidator = new oav.LiveValidator(liveValidatorOptions);
|
||||
await apiValidator.initialize(); // Note that for a large number of specs this can take some time.
|
||||
|
||||
// After `initialize()` finishes we are ready to validate
|
||||
const validationResult = apiValidator.validateLiveRequestResponse(requestResponsePair)
|
||||
const validationResult = apiValidator.validateLiveRequestResponse(requestResponsePair);
|
||||
```
|
||||
|
||||
### Regression testing
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 413 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.4 MiB |
|
@ -115,6 +115,11 @@ export const builder: yargs.CommandBuilder = {
|
|||
string: true,
|
||||
demandOption: false,
|
||||
},
|
||||
verbose: {
|
||||
describe: "log verbose",
|
||||
default: false,
|
||||
boolean: true,
|
||||
},
|
||||
};
|
||||
|
||||
export async function handler(argv: yargs.Arguments): Promise<void> {
|
||||
|
@ -178,6 +183,7 @@ export async function handler(argv: yargs.Arguments): Promise<void> {
|
|||
from: argv.from,
|
||||
to: argv.to,
|
||||
runId: argv.runId,
|
||||
verbose: argv.verbose,
|
||||
};
|
||||
const generator = inversifyGetInstance(PostmanCollectionGenerator, opt);
|
||||
await generator.GenerateCollection();
|
||||
|
|
|
@ -125,7 +125,7 @@ export class JsonLoader implements Loader<Json> {
|
|||
throw new Error(`cache not found for ${filePath}`);
|
||||
}
|
||||
|
||||
refObj = jsonPointer.get(cache.resolved!, refObjPath);
|
||||
refObj = jsonPointer.get(cache.resolved! as any, refObjPath);
|
||||
(object as any).$ref = $ref;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,9 +101,9 @@ export class BodyTransformer {
|
|||
|
||||
if (typeof dst === "object" && typeof src === "object") {
|
||||
const result: any = { ...dst };
|
||||
if (dst !== null) {
|
||||
if (dst !== null && src !== null) {
|
||||
for (const key of Object.keys(dst)) {
|
||||
if (src !== null && key in src) {
|
||||
if (key in src) {
|
||||
result[key] = this.innerDeepMerge(
|
||||
dst[key],
|
||||
src[key],
|
||||
|
@ -113,7 +113,7 @@ export class BodyTransformer {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (src !== null) {
|
||||
if (src !== null && dst !== null) {
|
||||
for (const key of Object.keys(src)) {
|
||||
if (!(key in dst)) {
|
||||
result[key] = src[key];
|
||||
|
|
|
@ -34,6 +34,7 @@ export interface PostmanCollectionGeneratorOption
|
|||
from?: string;
|
||||
to?: string;
|
||||
runId?: string;
|
||||
verbose?: boolean;
|
||||
}
|
||||
|
||||
@injectable()
|
||||
|
@ -82,6 +83,7 @@ export class PostmanCollectionGenerator {
|
|||
from: this.opt.from,
|
||||
to: this.opt.to,
|
||||
skipCleanUp: this.opt.skipCleanUp,
|
||||
verbose: this.opt.verbose,
|
||||
};
|
||||
|
||||
const client = inversifyGetInstance(PostmanCollectionRunnerClient, opts);
|
||||
|
|
|
@ -65,6 +65,7 @@ export interface PostmanCollectionRunnerClientOption extends BlobUploaderOption,
|
|||
skipCleanUp?: boolean;
|
||||
from?: string;
|
||||
to?: string;
|
||||
verbose?: boolean;
|
||||
}
|
||||
|
||||
function makeid(length: number): string {
|
||||
|
@ -101,6 +102,7 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
public collection: Collection;
|
||||
public collectionEnv: VariableScope;
|
||||
private postmanTestScript: PostmanTestScript;
|
||||
private stepNameSet: Map<string, number>;
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility
|
||||
constructor(
|
||||
@inject(TYPES.opts) private opts: PostmanCollectionRunnerClientOption,
|
||||
|
@ -120,6 +122,7 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
blobConnectionString: process.env.blobConnectionString || "",
|
||||
baseUrl: "https://management.azure.com",
|
||||
});
|
||||
this.stepNameSet = new Map<string, number>();
|
||||
this.collection = new Collection();
|
||||
this.collection.name = this.opts.testScenarioFileName;
|
||||
this.collection.id = this.opts.runId!;
|
||||
|
@ -204,7 +207,14 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
this.auth(stepEnv.env);
|
||||
const pathEnv = new ReflectiveVariableEnv(":", "");
|
||||
const item = new Item();
|
||||
item.name = step.step!;
|
||||
if (!this.stepNameSet.has(step.step!)) {
|
||||
item.name = step.step!;
|
||||
this.stepNameSet.set(step.step, 0);
|
||||
} else {
|
||||
const cnt = this.stepNameSet.get(step.step!)! + 1;
|
||||
item.name = `${step.step}_${cnt}`;
|
||||
this.stepNameSet.set(step.step, cnt);
|
||||
}
|
||||
item.request = new Request({
|
||||
name: step.exampleFilePath,
|
||||
method: step.operation._method as string,
|
||||
|
@ -263,8 +273,10 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
this.addTestScript(item, ["DetailResponseLog", "StatusCodeAssertion"], getOverwriteVariables());
|
||||
const scriptTypes: TestScriptType[] = this.opts.verbose
|
||||
? ["DetailResponseLog", "StatusCodeAssertion"]
|
||||
: ["StatusCodeAssertion"];
|
||||
this.addTestScript(item, scriptTypes, getOverwriteVariables());
|
||||
item.request.url = new Url({
|
||||
path: pathEnv.resolveString(step.operation._path._pathTemplate, "{", "}"),
|
||||
host: this.opts.baseUrl,
|
||||
|
@ -279,7 +291,7 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
operationId: step.operation.operationId || "",
|
||||
exampleName: step.exampleFile!,
|
||||
itemName: item.name,
|
||||
step: step.step,
|
||||
step: item.name,
|
||||
});
|
||||
this.addAsLongRunningOperationItem(item);
|
||||
} else {
|
||||
|
@ -288,7 +300,7 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
operationId: step.operation.operationId || "",
|
||||
exampleName: step.exampleFile!,
|
||||
itemName: item.name,
|
||||
step: step.step,
|
||||
step: item.name,
|
||||
});
|
||||
this.collection.items.add(item);
|
||||
}
|
||||
|
@ -298,7 +310,7 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
this.generatedGetOperationItem(
|
||||
item.name,
|
||||
item.request.url.toString(),
|
||||
step.step,
|
||||
item.name,
|
||||
step.operation._method
|
||||
)
|
||||
);
|
||||
|
@ -325,10 +337,13 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
|
||||
private addTestScript(
|
||||
item: Item,
|
||||
types: TestScriptType[] = ["DetailResponseLog", "StatusCodeAssertion"],
|
||||
types: TestScriptType[] = ["StatusCodeAssertion"],
|
||||
overwriteVariables?: Map<string, string>,
|
||||
armTemplate?: ArmTemplate
|
||||
) {
|
||||
if (this.opts.verbose) {
|
||||
types.push("DetailResponseLog");
|
||||
}
|
||||
if (overwriteVariables !== undefined) {
|
||||
types.push("OverwriteVariables");
|
||||
}
|
||||
|
@ -390,6 +405,9 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
raw: JSON.stringify(body, null, 2),
|
||||
});
|
||||
this.addAuthorizationHeader(item);
|
||||
const scriptTypes: TestScriptType[] = this.opts.verbose
|
||||
? ["StatusCodeAssertion", "DetailResponseLog"]
|
||||
: ["StatusCodeAssertion"];
|
||||
item.events.add(
|
||||
new Event({
|
||||
listen: "test",
|
||||
|
@ -397,7 +415,7 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
type: "text/javascript",
|
||||
exec: this.postmanTestScript.generateScript({
|
||||
name: "response status code assertion.",
|
||||
types: ["DetailResponseLog", "StatusCodeAssertion"],
|
||||
types: scriptTypes,
|
||||
variables: undefined,
|
||||
}),
|
||||
},
|
||||
|
@ -405,12 +423,15 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
);
|
||||
this.collection.items.add(item);
|
||||
this.addAsLongRunningOperationItem(item, true);
|
||||
const generatedGetScriptTypes: TestScriptType[] = this.opts.verbose
|
||||
? ["DetailResponseLog", "ExtractARMTemplateOutput"]
|
||||
: ["ExtractARMTemplateOutput"];
|
||||
const generatedGetOperationItem = this.generatedGetOperationItem(
|
||||
item.name,
|
||||
item.request.url.toString(),
|
||||
step.step,
|
||||
"put",
|
||||
["DetailResponseLog", "ExtractARMTemplateOutput"],
|
||||
generatedGetScriptTypes,
|
||||
armTemplate
|
||||
);
|
||||
this.collection.items.add(generatedGetOperationItem);
|
||||
|
@ -586,6 +607,7 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
runId: this.opts.runId,
|
||||
swaggerFilePaths: this.opts.swaggerFilePaths,
|
||||
validationLevel: this.opts.validationLevel,
|
||||
verbose: this.opts.verbose,
|
||||
};
|
||||
const reportAnalyzer = inversifyGetInstance(NewmanReportAnalyzer, opts);
|
||||
await reportAnalyzer.analyze();
|
||||
|
@ -604,7 +626,7 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
url: string,
|
||||
step: string,
|
||||
prevMethod: string = "put",
|
||||
scriptTypes: TestScriptType[] = ["DetailResponseLog"],
|
||||
scriptTypes: TestScriptType[] = [],
|
||||
armTemplate?: ArmTemplate
|
||||
): Item {
|
||||
const item = new Item({
|
||||
|
@ -652,7 +674,6 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
postman.setNextRequest($(nextRequest))
|
||||
}
|
||||
else{
|
||||
console.log(pm.response.text())
|
||||
const terminalStatus = ["Succeeded", "Failed", "Canceled"]
|
||||
if(pm.response.json().status!==undefined&&terminalStatus.indexOf(pm.response.json().status)===-1){
|
||||
postman.setNextRequest('${delay.name}')
|
||||
|
@ -661,7 +682,6 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
}
|
||||
}
|
||||
}catch(err){
|
||||
console.log(err)
|
||||
postman.setNextRequest($(nextRequest))
|
||||
}`,
|
||||
},
|
||||
|
@ -735,6 +755,7 @@ export class PostmanCollectionRunnerClient implements TestScenarioRunnerClient {
|
|||
this.collectionEnv.set("client_id", env.get("client_id"), "string");
|
||||
this.collectionEnv.set("client_secret", env.get("client_secret"), "string");
|
||||
this.collectionEnv.set("resourceGroupName", env.get("resourceGroupName"), "string");
|
||||
this.collectionEnv.set("subscriptionId", env.get("subscriptionId"), "string");
|
||||
ret.events.add(
|
||||
new Event({
|
||||
listen: "test",
|
||||
|
|
|
@ -16,6 +16,7 @@ export interface NewmanReportAnalyzerOption extends NewmanReportParserOption {
|
|||
runId?: string;
|
||||
swaggerFilePaths?: string[];
|
||||
validationLevel?: ValidationLevel;
|
||||
verbose?: boolean;
|
||||
}
|
||||
|
||||
@injectable()
|
||||
|
@ -31,6 +32,7 @@ export class NewmanReportAnalyzer {
|
|||
reportOutputFilePath: defaultQualityReportFilePath(this.opts.newmanReportFilePath),
|
||||
swaggerFilePaths: [],
|
||||
validationLevel: "validate-request-response",
|
||||
verbose: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -59,6 +61,7 @@ export class NewmanReportAnalyzer {
|
|||
runId: this.opts.runId,
|
||||
testScenarioName: testScenarioName,
|
||||
validationLevel: this.opts.validationLevel,
|
||||
verbose: this.opts.verbose,
|
||||
};
|
||||
const reportGenerator = inversifyGetInstance(ReportGenerator, reportGeneratorOption);
|
||||
await reportGenerator.generateReport();
|
||||
|
|
|
@ -103,6 +103,7 @@ export interface ReportGeneratorOption
|
|||
testScenarioName?: string;
|
||||
runId?: string;
|
||||
validationLevel?: ValidationLevel;
|
||||
verbose?: boolean;
|
||||
}
|
||||
|
||||
@injectable()
|
||||
|
@ -133,6 +134,7 @@ export class ReportGenerator {
|
|||
testDefFilePath: "",
|
||||
runId: uuid.v4(),
|
||||
validationLevel: "validate-request-response",
|
||||
verbose: false,
|
||||
});
|
||||
const swaggerFileAbsolutePaths = this.opts.swaggerFilePaths!.map((it) => path.resolve(it));
|
||||
this.exampleQualityValidator = ExampleQualityValidator.create({
|
||||
|
@ -265,7 +267,9 @@ export class ReportGenerator {
|
|||
}
|
||||
}
|
||||
}
|
||||
console.log(JSON.stringify(this.swaggerExampleQualityResult, null, 2));
|
||||
if (this.opts.verbose) {
|
||||
console.log(JSON.stringify(this.swaggerExampleQualityResult, null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
public async generateMarkdownQualityReport() {
|
||||
|
@ -416,9 +420,8 @@ export class ReportGenerator {
|
|||
})
|
||||
.filter((it) => it !== undefined) as ResponseDiffItem[];
|
||||
return delta;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (err) {}
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ export function setObject(
|
|||
ptr: string,
|
||||
value: unknown,
|
||||
overwrite = true
|
||||
): void {
|
||||
): any {
|
||||
let result;
|
||||
try {
|
||||
if (overwrite || !jsonPointer.has(doc, ptr)) {
|
||||
|
|
|
@ -3334,7 +3334,7 @@
|
|||
},
|
||||
"buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
|
||||
},
|
||||
"buffer-from": {
|
||||
|
@ -4168,7 +4168,7 @@
|
|||
},
|
||||
"difflib": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/difflib/-/difflib-0.2.4.tgz",
|
||||
"resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz",
|
||||
"integrity": "sha1-teMDYabbAjF21WKJLbhZQKcY9H4=",
|
||||
"requires": {
|
||||
"heap": ">= 0.2.0"
|
||||
|
@ -5929,7 +5929,7 @@
|
|||
},
|
||||
"heap": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/heap/-/heap-0.2.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz",
|
||||
"integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw="
|
||||
},
|
||||
"hosted-git-info": {
|
||||
|
@ -10175,12 +10175,12 @@
|
|||
},
|
||||
"lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
|
||||
},
|
||||
"lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
|
||||
},
|
||||
"lodash.isequal": {
|
||||
|
@ -10190,22 +10190,22 @@
|
|||
},
|
||||
"lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
|
||||
},
|
||||
"lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
|
||||
},
|
||||
"lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
|
||||
},
|
||||
"lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
|
||||
},
|
||||
"lodash.merge": {
|
||||
|
@ -10221,7 +10221,7 @@
|
|||
},
|
||||
"lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
|
||||
},
|
||||
"lodash.sortby": {
|
||||
|
@ -11218,7 +11218,7 @@
|
|||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"object-copy": {
|
||||
|
@ -11998,7 +11998,7 @@
|
|||
},
|
||||
"process": {
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/openapi-platform/npm/registry/process/-/process-0.11.10.tgz",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
|
|
Загрузка…
Ссылка в новой задаче