feat(接口测试): 接口定义增加自动重定向

--story=1010712 --user=王孝刚 【接口测试】MS接口测试目前只支持跟随重定向,不支持自动重定向,需提供支持 #19501
https://www.tapd.cn/55049933/s/1309581
This commit is contained in:
wxg0103 2022-12-01 15:54:26 +08:00 committed by wxg0103
parent 090e877a47
commit 5dd07611f3
10 changed files with 1393 additions and 787 deletions

View File

@ -76,6 +76,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
private List<KeyValue> rest;
private String url;
private boolean followRedirects;
private boolean autoRedirects;
private boolean doMultipartPost;
private String useEnvironment;
private List<KeyValue> arguments;
@ -123,6 +124,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
sampler.setMethod(this.getMethod());
sampler.setContentEncoding(StandardCharsets.UTF_8.name());
sampler.setFollowRedirects(this.isFollowRedirects());
sampler.setAutoRedirects(this.isAutoRedirects());
sampler.setUseKeepAlive(true);
sampler.setDoMultipart(this.isDoMultipartPost());
if (config.getConfig() == null) {

View File

@ -30,10 +30,15 @@
</el-row>
<el-row style="margin: 20px">
<span style="margin-right: 10px">
<el-checkbox class="follow-redirects-item" v-model="request.followRedirects">{{
<el-checkbox class="follow-redirects-item" v-model="request.followRedirects" @change="changeFollow">{{
$t('api_test.request.follow_redirects')
}}</el-checkbox>
</span>
<span style="margin-left: 10px; margin-right: 10px">
<el-checkbox class="follow-redirects-item" v-model="request.autoRedirects" @change="changeAuto">{{
$t('api_definition.request.auto_redirects')
}}</el-checkbox>
</span>
</el-row>
</div>
</template>
@ -48,6 +53,18 @@ export default {
default: false,
},
},
methods: {
changeFollow() {
if (this.request.followRedirects) {
this.request.autoRedirects = false;
}
},
changeAuto() {
if (this.request.autoRedirects) {
this.request.followRedirects = false;
}
},
},
};
</script>

View File

@ -28,6 +28,9 @@ const message = {
plan_count: '{0} [test plan]',
case_is_referenced: '{0} cases have reference relationships',
scenario_is_referenced: '{0} scenarios have reference relationships',
request: {
auto_redirects: 'Auto redirects',
},
},
home: {
dashboard: {

View File

@ -28,6 +28,9 @@ const message = {
plan_count: '{0}个[测试计划]',
case_is_referenced: '有{0}个用例存在引用关系',
scenario_is_referenced: '有{0}个场景存在引用关系',
request: {
auto_redirects: '自动重定向',
},
},
home: {
dashboard: {

View File

@ -28,6 +28,9 @@ const message = {
plan_count: '{0}個[测试計劃]',
case_is_referenced: '有{0}個用例存在引用關係',
scenario_is_referenced: '有{0}個場景存在引用關係',
request: {
auto_redirects: '自動重定向',
},
},
home: {
dashboard: {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
const INDENT = ' '; // 缩进2空格
const INDENT = " "; // 缩进2空格
export class Element {
constructor(name, attributes, value) {
this.indent = '';
this.name = name; // 标签名
this.indent = "";
this.name = name; // 标签名
this.attributes = attributes || {}; // 属性
this.value = undefined; // 基础类型的内容
this.elements = []; // 子节点
@ -34,35 +34,37 @@ export class Element {
commonValue(tag, name, value, defaultValue) {
let v = this.getDefault(value, defaultValue);
return this.add(new Element(tag, {name: name}, v));
return this.add(new Element(tag, { name: name }, v));
}
boolProp(name, value, defaultValue) {
return this.commonValue('boolProp', name, value, defaultValue);
return this.commonValue("boolProp", name, value, defaultValue);
}
intProp(name, value, defaultValue) {
return this.commonValue('intProp', name, value, defaultValue);
return this.commonValue("intProp", name, value, defaultValue);
}
longProp(name, value, defaultValue) {
return this.commonValue('longProp', name, value, defaultValue);
return this.commonValue("longProp", name, value, defaultValue);
}
stringProp(name, value, defaultValue) {
return this.commonValue('stringProp', name, value, defaultValue);
return this.commonValue("stringProp", name, value, defaultValue);
}
collectionProp(name) {
return this.commonValue('collectionProp', name);
return this.commonValue("collectionProp", name);
}
elementProp(name, elementType) {
return this.add(new Element('elementProp', {name: name, elementType: elementType}));
return this.add(
new Element("elementProp", { name: name, elementType: elementType })
);
}
isEmptyValue() {
return this.value === undefined || this.value === '';
return this.value === undefined || this.value === "";
}
isEmptyElement() {
@ -74,8 +76,15 @@ export class Element {
}
replace(str) {
if (!str || !(typeof str === 'string')) return str;
return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/'/g, "&apos;").replace(/"/g, "&quot;");
if (!str || !(typeof str === "string")) {
return str;
}
return str
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/'/g, "&apos;")
.replace(/"/g, "&quot;");
}
toXML(indent) {
@ -90,16 +99,21 @@ export class Element {
}
start() {
let str = this.indent + '<' + this.replace(this.name);
let str = this.indent + "<" + this.replace(this.name);
for (let key in this.attributes) {
if (Object.prototype.hasOwnProperty.call(this.attributes, key)) {
str += ' ' + this.replace(key) + '="' + this.replace(this.attributes[key]) + '"';
str +=
" " +
this.replace(key) +
'="' +
this.replace(this.attributes[key]) +
'"';
}
}
if (this.isEmpty()) {
str += '/>';
str += "/>";
} else {
str += '>';
str += ">";
}
return str;
}
@ -109,11 +123,11 @@ export class Element {
return this.replace(this.value);
}
let str = '';
let str = "";
let parent = this;
if (this.elements.length > 0) {
str += '\n';
this.elements.forEach(e => {
str += "\n";
this.elements.forEach((e) => {
e.indent += parent.indent + INDENT;
str += e.toXML();
});
@ -123,9 +137,9 @@ export class Element {
end() {
if (this.isEmpty()) {
return '\n';
return "\n";
}
let str = '</' + this.replace(this.name) + '>\n';
let str = "</" + this.replace(this.name) + ">\n";
if (!this.isEmptyValue()) {
return str;
}
@ -138,7 +152,7 @@ export class Element {
// HashTree, 只能添加TestElement的子元素没有基础类型内容
export class HashTree extends Element {
constructor() {
super('hashTree');
super("hashTree");
}
add(te) {
@ -173,15 +187,15 @@ export class DefaultTestElement extends TestElement {
super(tag, {
guiclass: guiclass,
testclass: testclass,
testname: testname === undefined ? tag + ' Name' : testname,
enabled: enabled || true
testname: testname === undefined ? tag + " Name" : testname,
enabled: enabled || true,
});
}
}
export class TestPlan extends DefaultTestElement {
constructor(testName, props) {
super('TestPlan', 'TestPlanGui', 'TestPlan', testName);
super("TestPlan", "TestPlanGui", "TestPlan", testName);
props = props || {};
this.boolProp("TestPlan.functional_mode", props.mode, false);
@ -189,13 +203,19 @@ export class TestPlan extends DefaultTestElement {
this.boolProp("TestPlan.tearDown_on_shutdown", props.tos, true);
this.stringProp("TestPlan.comments", props.comments);
this.stringProp("TestPlan.user_define_classpath", props.classpath);
this.add(new ElementArguments(props.args, "TestPlan.user_defined_variables", "User Defined Variables"));
this.add(
new ElementArguments(
props.args,
"TestPlan.user_defined_variables",
"User Defined Variables"
)
);
}
}
export class ThreadGroup extends DefaultTestElement {
constructor(testName, props) {
super('ThreadGroup', 'ThreadGroupGui', 'ThreadGroup', testName);
super("ThreadGroup", "ThreadGroupGui", "ThreadGroup", testName);
props = props || {};
this.intProp("ThreadGroup.num_threads", props.threads, 1);
@ -211,72 +231,139 @@ export class ThreadGroup extends DefaultTestElement {
guiclass: "LoopControlPanel",
testclass: "LoopController",
testname: "Loop Controller",
enabled: "true"
enabled: "true",
};
let loopProps = props.loopProps || {};
let loopController = this.add(new Element('elementProp', loopAttrs));
loopController.boolProp('LoopController.continue_forever', loopProps.continue, false);
loopController.stringProp('LoopController.loops', loopProps.loops, 1);
let loopController = this.add(new Element("elementProp", loopAttrs));
loopController.boolProp(
"LoopController.continue_forever",
loopProps.continue,
false
);
loopController.stringProp("LoopController.loops", loopProps.loops, 1);
}
}
export class DubboSample extends DefaultTestElement {
constructor(testName, request = {}) {
super('io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample',
'io.github.ningyu.jmeter.plugin.dubbo.gui.DubboSampleGui',
'io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample', testName);
super(
"io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample",
"io.github.ningyu.jmeter.plugin.dubbo.gui.DubboSampleGui",
"io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample",
testName
);
this.request = request;
this.stringProp("FIELD_DUBBO_CONFIG_CENTER_PROTOCOL", this.request.configCenter.protocol);
this.stringProp("FIELD_DUBBO_CONFIG_CENTER_GROUP", this.request.configCenter.group);
this.stringProp("FIELD_DUBBO_CONFIG_CENTER_NAMESPACE", this.request.configCenter.namespace);
this.stringProp("FIELD_DUBBO_CONFIG_CENTER_USER_NAME", this.request.configCenter.username);
this.stringProp("FIELD_DUBBO_CONFIG_CENTER_PASSWORD", this.request.configCenter.password);
this.stringProp("FIELD_DUBBO_CONFIG_CENTER_ADDRESS", this.request.configCenter.address);
this.stringProp("FIELD_DUBBO_CONFIG_CENTER_TIMEOUT", this.request.configCenter.timeout);
this.stringProp(
"FIELD_DUBBO_CONFIG_CENTER_PROTOCOL",
this.request.configCenter.protocol
);
this.stringProp(
"FIELD_DUBBO_CONFIG_CENTER_GROUP",
this.request.configCenter.group
);
this.stringProp(
"FIELD_DUBBO_CONFIG_CENTER_NAMESPACE",
this.request.configCenter.namespace
);
this.stringProp(
"FIELD_DUBBO_CONFIG_CENTER_USER_NAME",
this.request.configCenter.username
);
this.stringProp(
"FIELD_DUBBO_CONFIG_CENTER_PASSWORD",
this.request.configCenter.password
);
this.stringProp(
"FIELD_DUBBO_CONFIG_CENTER_ADDRESS",
this.request.configCenter.address
);
this.stringProp(
"FIELD_DUBBO_CONFIG_CENTER_TIMEOUT",
this.request.configCenter.timeout
);
this.stringProp("FIELD_DUBBO_REGISTRY_PROTOCOL", this.request.registryCenter.protocol);
this.stringProp("FIELD_DUBBO_REGISTRY_GROUP", this.request.registryCenter.group);
this.stringProp("FIELD_DUBBO_REGISTRY_USER_NAME", this.request.registryCenter.username);
this.stringProp("FIELD_DUBBO_REGISTRY_PASSWORD", this.request.registryCenter.password);
this.stringProp(
"FIELD_DUBBO_REGISTRY_PROTOCOL",
this.request.registryCenter.protocol
);
this.stringProp(
"FIELD_DUBBO_REGISTRY_GROUP",
this.request.registryCenter.group
);
this.stringProp(
"FIELD_DUBBO_REGISTRY_USER_NAME",
this.request.registryCenter.username
);
this.stringProp(
"FIELD_DUBBO_REGISTRY_PASSWORD",
this.request.registryCenter.password
);
this.stringProp("FIELD_DUBBO_ADDRESS", this.request.registryCenter.address);
this.stringProp("FIELD_DUBBO_REGISTRY_TIMEOUT", this.request.registryCenter.timeout);
this.stringProp(
"FIELD_DUBBO_REGISTRY_TIMEOUT",
this.request.registryCenter.timeout
);
this.stringProp("FIELD_DUBBO_TIMEOUT", this.request.consumerAndService.timeout);
this.stringProp("FIELD_DUBBO_VERSION", this.request.consumerAndService.version);
this.stringProp("FIELD_DUBBO_RETRIES", this.request.consumerAndService.retries);
this.stringProp(
"FIELD_DUBBO_TIMEOUT",
this.request.consumerAndService.timeout
);
this.stringProp(
"FIELD_DUBBO_VERSION",
this.request.consumerAndService.version
);
this.stringProp(
"FIELD_DUBBO_RETRIES",
this.request.consumerAndService.retries
);
this.stringProp("FIELD_DUBBO_GROUP", this.request.consumerAndService.group);
this.stringProp("FIELD_DUBBO_CONNECTIONS", this.request.consumerAndService.connections);
this.stringProp("FIELD_DUBBO_LOADBALANCE", this.request.consumerAndService.loadBalance);
this.stringProp(
"FIELD_DUBBO_CONNECTIONS",
this.request.consumerAndService.connections
);
this.stringProp(
"FIELD_DUBBO_LOADBALANCE",
this.request.consumerAndService.loadBalance
);
this.stringProp("FIELD_DUBBO_ASYNC", this.request.consumerAndService.async);
this.stringProp("FIELD_DUBBO_CLUSTER", this.request.consumerAndService.cluster);
this.stringProp(
"FIELD_DUBBO_CLUSTER",
this.request.consumerAndService.cluster
);
this.stringProp("FIELD_DUBBO_RPC_PROTOCOL", this.request.protocol);
this.stringProp("FIELD_DUBBO_INTERFACE", this.request.interface);
this.stringProp("FIELD_DUBBO_METHOD", this.request.method);
this.intProp("FIELD_DUBBO_METHOD_ARGS_SIZE", this.request.args.length);
this.intProp("FIELD_DUBBO_ATTACHMENT_ARGS_SIZE", this.request.attachmentArgs.length);
this.intProp(
"FIELD_DUBBO_ATTACHMENT_ARGS_SIZE",
this.request.attachmentArgs.length
);
this.request.args.forEach((arg, i) => {
if (!!arg.name || !!arg.value) {
let index = i + 1;
this.stringProp("FIELD_DUBBO_METHOD_ARGS_PARAM_TYPE" + index, arg.name);
this.stringProp("FIELD_DUBBO_METHOD_ARGS_PARAM_VALUE" + index, arg.value);
this.stringProp(
"FIELD_DUBBO_METHOD_ARGS_PARAM_VALUE" + index,
arg.value
);
}
})
});
this.request.attachmentArgs.forEach((arg, i) => {
if (!!arg.name || !!arg.value) {
let index = i + 1;
this.stringProp("FIELD_DUBBO_ATTACHMENT_ARGS_KEY" + index, arg.name);
this.stringProp("FIELD_DUBBO_ATTACHMENT_ARGS_VALUE" + index, arg.value);
}
})
});
}
}
export class JDBCSampler extends DefaultTestElement {
constructor(testName, request = {}) {
super('JDBCSampler', 'TestBeanGUI', 'JDBCSampler', testName);
super("JDBCSampler", "TestBeanGUI", "JDBCSampler", testName);
this.stringProp("dataSource", request.dataSource);
this.stringProp("query", request.query);
@ -286,14 +373,14 @@ export class JDBCSampler extends DefaultTestElement {
this.stringProp("queryArguments");
this.stringProp("queryArgumentsTypes");
this.stringProp("resultSetMaxRows");
this.stringProp("resultSetHandler", 'Store as String');
this.stringProp("queryType", 'Callable Statement');
this.stringProp("resultSetHandler", "Store as String");
this.stringProp("queryType", "Callable Statement");
}
}
export class TCPSampler extends DefaultTestElement {
constructor(testName, request = {}) {
super('TCPSampler', 'TCPSamplerGui', 'TCPSampler', testName);
super("TCPSampler", "TCPSamplerGui", "TCPSampler", testName);
this.stringProp("TCPSampler.classname", request.classname);
this.stringProp("TCPSampler.server", request.server);
@ -313,7 +400,12 @@ export class TCPSampler extends DefaultTestElement {
export class HTTPSamplerProxy extends DefaultTestElement {
constructor(testName, options = {}) {
super('HTTPSamplerProxy', 'HttpTestSampleGui', 'HTTPSamplerProxy', testName);
super(
"HTTPSamplerProxy",
"HttpTestSampleGui",
"HTTPSamplerProxy",
testName
);
this.stringProp("HTTPSampler.domain", options.domain);
this.stringProp("HTTPSampler.protocol", options.protocol);
@ -327,46 +419,62 @@ export class HTTPSamplerProxy extends DefaultTestElement {
this.stringProp("HTTPSampler.port", options.port);
}
if (options.connectTimeout) {
this.stringProp('HTTPSampler.connect_timeout', options.connectTimeout);
this.stringProp("HTTPSampler.connect_timeout", options.connectTimeout);
}
if (options.responseTimeout) {
this.stringProp('HTTPSampler.response_timeout', options.responseTimeout);
this.stringProp("HTTPSampler.response_timeout", options.responseTimeout);
}
if (options.followRedirects) {
this.boolProp('HTTPSampler.follow_redirects', options.followRedirects, true);
this.boolProp(
"HTTPSampler.follow_redirects",
options.followRedirects,
true
);
}
if (options.autoRedirects) {
this.boolProp("HTTPSampler.auto_redirects", options.autoRedirects, false);
}
this.boolProp("HTTPSampler.use_keepalive", options.keepalive, true);
this.boolProp("HTTPSampler.DO_MULTIPART_POST", options.doMultipartPost, false);
this.boolProp(
"HTTPSampler.DO_MULTIPART_POST",
options.doMultipartPost,
false
);
}
}
// 这是一个Element
export class HTTPSamplerArguments extends Element {
constructor(args) {
super('elementProp', {
super("elementProp", {
name: "HTTPsampler.Arguments", // s必须小写
elementType: "Arguments",
guiclass: "HTTPArgumentsPanel",
testclass: "Arguments",
enabled: "true"
enabled: "true",
});
this.args = args || [];
let collectionProp = this.collectionProp('Arguments.arguments');
this.args.forEach(arg => {
if (arg.enable === true || arg.enable === undefined) { // 非禁用的条件加入执行
let elementProp = collectionProp.elementProp(arg.name, 'HTTPArgument');
elementProp.boolProp('HTTPArgument.always_encode', arg.encode, true);
elementProp.boolProp('HTTPArgument.use_equals', arg.equals, true);
let collectionProp = this.collectionProp("Arguments.arguments");
this.args.forEach((arg) => {
if (arg.enable === true || arg.enable === undefined) {
// 非禁用的条件加入执行
let elementProp = collectionProp.elementProp(arg.name, "HTTPArgument");
elementProp.boolProp("HTTPArgument.always_encode", arg.encode, true);
elementProp.boolProp("HTTPArgument.use_equals", arg.equals, true);
if (arg.name) {
elementProp.stringProp('Argument.name', arg.name);
elementProp.stringProp("Argument.name", arg.name);
}
elementProp.stringProp('Argument.value', arg.value);
elementProp.stringProp('Argument.metadata', arg.metadata || "=");
elementProp.stringProp("Argument.value", arg.value);
elementProp.stringProp("Argument.metadata", arg.metadata || "=");
if (arg.contentType) {
elementProp.stringProp('HTTPArgument.content_type', arg.contentType, "");
elementProp.stringProp(
"HTTPArgument.content_type",
arg.contentType,
""
);
}
}
});
@ -375,51 +483,59 @@ export class HTTPSamplerArguments extends Element {
export class HTTPsamplerFiles extends Element {
constructor(args) {
super('elementProp', {
super("elementProp", {
name: "HTTPsampler.Files",
elementType: "HTTPFileArgs",
});
this.args = args || {};
let collectionProp = this.collectionProp('HTTPFileArgs.files');
this.args.forEach(arg => {
let elementProp = collectionProp.elementProp(arg.value, 'HTTPFileArg');
elementProp.stringProp('File.path', arg.value);
elementProp.stringProp('File.paramname', arg.name);
elementProp.stringProp('File.mimetype', arg.contentType || "application/octet-stream");
let collectionProp = this.collectionProp("HTTPFileArgs.files");
this.args.forEach((arg) => {
let elementProp = collectionProp.elementProp(arg.value, "HTTPFileArg");
elementProp.stringProp("File.path", arg.value);
elementProp.stringProp("File.paramname", arg.name);
elementProp.stringProp(
"File.mimetype",
arg.contentType || "application/octet-stream"
);
});
}
}
export class CookieManager extends DefaultTestElement {
constructor(testName) {
super('CookieManager', 'CookiePanel', 'CookieManager', testName);
this.collectionProp('CookieManager.cookies');
this.boolProp('CookieManager.clearEachIteration', false, false);
this.boolProp('CookieManager.controlledByThreadGroup', false, false);
super("CookieManager", "CookiePanel", "CookieManager", testName);
this.collectionProp("CookieManager.cookies");
this.boolProp("CookieManager.clearEachIteration", false, false);
this.boolProp("CookieManager.controlledByThreadGroup", false, false);
}
}
export class DurationAssertion extends DefaultTestElement {
constructor(testName, duration) {
super('DurationAssertion', 'DurationAssertionGui', 'DurationAssertion', testName);
super(
"DurationAssertion",
"DurationAssertionGui",
"DurationAssertion",
testName
);
this.duration = duration || 0;
this.stringProp('DurationAssertion.duration', this.duration);
this.stringProp("DurationAssertion.duration", this.duration);
}
}
export class ResponseAssertion extends DefaultTestElement {
constructor(testName, assertion) {
super('ResponseAssertion', 'AssertionGui', 'ResponseAssertion', testName);
super("ResponseAssertion", "AssertionGui", "ResponseAssertion", testName);
this.assertion = assertion || {};
this.stringProp('Assertion.test_field', this.assertion.field);
this.boolProp('Assertion.assume_success', this.assertion.assumeSuccess);
this.intProp('Assertion.test_type', this.assertion.type);
this.stringProp('Assertion.custom_message', this.assertion.message);
this.stringProp("Assertion.test_field", this.assertion.field);
this.boolProp("Assertion.assume_success", this.assertion.assumeSuccess);
this.intProp("Assertion.test_type", this.assertion.type);
this.stringProp("Assertion.custom_message", this.assertion.message);
let collectionProp = this.collectionProp('Asserion.test_strings');
let collectionProp = this.collectionProp("Asserion.test_strings");
let random = Math.floor(Math.random() * 10000);
collectionProp.stringProp(random, this.assertion.value);
}
@ -427,54 +543,59 @@ export class ResponseAssertion extends DefaultTestElement {
export class JSONPathAssertion extends DefaultTestElement {
constructor(testName, jsonPath) {
super('JSONPathAssertion', 'JSONPathAssertionGui', 'JSONPathAssertion', testName);
super(
"JSONPathAssertion",
"JSONPathAssertionGui",
"JSONPathAssertion",
testName
);
this.jsonPath = jsonPath || {};
this.stringProp('JSON_PATH', this.jsonPath.expression);
this.stringProp('EXPECTED_VALUE', this.jsonPath.expect);
this.boolProp('JSONVALIDATION', true);
this.boolProp('EXPECT_NULL', false);
this.boolProp('INVERT', false);
this.boolProp('ISREGEX', true);
this.stringProp("JSON_PATH", this.jsonPath.expression);
this.stringProp("EXPECTED_VALUE", this.jsonPath.expect);
this.boolProp("JSONVALIDATION", true);
this.boolProp("EXPECT_NULL", false);
this.boolProp("INVERT", false);
this.boolProp("ISREGEX", true);
}
}
export class ResponseCodeAssertion extends ResponseAssertion {
constructor(testName, type, value, assumeSuccess, message) {
let assertion = {
field: 'Assertion.response_code',
field: "Assertion.response_code",
type: type,
value: value,
assumeSuccess: assumeSuccess,
message: message,
}
super(testName, assertion)
};
super(testName, assertion);
}
}
export class ResponseDataAssertion extends ResponseAssertion {
constructor(testName, type, value, assumeSuccess, message) {
let assertion = {
field: 'Assertion.response_data',
field: "Assertion.response_data",
type: type,
value: value,
assumeSuccess: assumeSuccess,
message: message,
}
super(testName, assertion)
};
super(testName, assertion);
}
}
export class ResponseHeadersAssertion extends ResponseAssertion {
constructor(testName, type, value, assumeSuccess, message) {
let assertion = {
field: 'Assertion.response_headers',
field: "Assertion.response_headers",
type: type,
value: value,
assumeSuccess: assumeSuccess,
message: message,
}
super(testName, assertion)
};
super(testName, assertion);
}
}
@ -482,10 +603,10 @@ export class BeanShellProcessor extends DefaultTestElement {
constructor(tag, guiclass, testclass, testname, processor) {
super(tag, guiclass, testclass, testname);
this.processor = processor || {};
this.boolProp('resetInterpreter', false);
this.stringProp('parameters');
this.stringProp('filename');
this.stringProp('script', processor.script);
this.boolProp("resetInterpreter", false);
this.stringProp("parameters");
this.stringProp("filename");
this.stringProp("script", processor.script);
}
}
@ -493,78 +614,106 @@ export class JSR223Processor extends DefaultTestElement {
constructor(tag, guiclass, testclass, testname, processor) {
super(tag, guiclass, testclass, testname);
this.processor = processor || {};
this.stringProp('cacheKey', 'true');
this.stringProp('filename');
this.stringProp('parameters');
this.stringProp('script', this.processor.script);
this.stringProp('scriptLanguage', this.processor.language);
this.stringProp("cacheKey", "true");
this.stringProp("filename");
this.stringProp("parameters");
this.stringProp("script", this.processor.script);
this.stringProp("scriptLanguage", this.processor.language);
}
}
export class JSR223PreProcessor extends JSR223Processor {
constructor(testName, processor) {
super('JSR223PreProcessor', 'TestBeanGUI', 'JSR223PreProcessor', testName, processor)
super(
"JSR223PreProcessor",
"TestBeanGUI",
"JSR223PreProcessor",
testName,
processor
);
}
}
export class JSR223PostProcessor extends JSR223Processor {
constructor(testName, processor) {
super('JSR223PostProcessor', 'TestBeanGUI', 'JSR223PostProcessor', testName, processor)
super(
"JSR223PostProcessor",
"TestBeanGUI",
"JSR223PostProcessor",
testName,
processor
);
}
}
export class BeanShellPreProcessor extends BeanShellProcessor {
constructor(testName, processor) {
super('BeanShellPreProcessor', 'TestBeanGUI', 'BeanShellPreProcessor', testName, processor)
super(
"BeanShellPreProcessor",
"TestBeanGUI",
"BeanShellPreProcessor",
testName,
processor
);
}
}
export class BeanShellPostProcessor extends BeanShellProcessor {
constructor(testName, processor) {
super('BeanShellPostProcessor', 'TestBeanGUI', 'BeanShellPostProcessor', testName, processor)
super(
"BeanShellPostProcessor",
"TestBeanGUI",
"BeanShellPostProcessor",
testName,
processor
);
}
}
export class IfController extends DefaultTestElement {
constructor(testName, controller = {}) {
super('IfController', 'IfControllerPanel', 'IfController', testName);
super("IfController", "IfControllerPanel", "IfController", testName);
this.stringProp('IfController.comments', controller.comments);
this.stringProp('IfController.condition', controller.condition);
this.boolProp('IfController.evaluateAll', controller.evaluateAll, false);
this.boolProp('IfController.useExpression', controller.useExpression, true);
this.stringProp("IfController.comments", controller.comments);
this.stringProp("IfController.condition", controller.condition);
this.boolProp("IfController.evaluateAll", controller.evaluateAll, false);
this.boolProp("IfController.useExpression", controller.useExpression, true);
}
}
export class TransactionController extends DefaultTestElement {
constructor(testName, controller = {}) {
super('TransactionController', 'TransactionControllerPanel', 'TransactionController', testName);
super(
"TransactionController",
"TransactionControllerPanel",
"TransactionController",
testName
);
this.stringProp('TransactionController.comments', controller.comments);
this.boolProp('TransactionController.parent', controller.parent, true);
this.stringProp("TransactionController.comments", controller.comments);
this.boolProp("TransactionController.parent", controller.parent, true);
}
}
export class ConstantTimer extends DefaultTestElement {
constructor(testName, timer = {}) {
super('ConstantTimer', 'ConstantTimerGui', 'ConstantTimer', testName);
super("ConstantTimer", "ConstantTimerGui", "ConstantTimer", testName);
this.stringProp('ConstantTimer.delay', timer.delay);
this.stringProp("ConstantTimer.delay", timer.delay);
}
}
export class HeaderManager extends DefaultTestElement {
constructor(testName, headers) {
super('HeaderManager', 'HeaderPanel', 'HeaderManager', testName);
super("HeaderManager", "HeaderPanel", "HeaderManager", testName);
this.headers = headers || [];
let collectionProp = this.collectionProp('HeaderManager.headers');
this.headers.forEach(header => {
let collectionProp = this.collectionProp("HeaderManager.headers");
this.headers.forEach((header) => {
if (header.enable === true || header.enable === undefined) {
let elementProp = collectionProp.elementProp('', 'Header');
elementProp.stringProp('Header.name', header.name);
elementProp.stringProp('Header.value', header.value);
let elementProp = collectionProp.elementProp("", "Header");
elementProp.stringProp("Header.name", header.name);
elementProp.stringProp("Header.value", header.value);
}
});
}
@ -572,57 +721,61 @@ export class HeaderManager extends DefaultTestElement {
export class DNSCacheManager extends DefaultTestElement {
constructor(testName, hosts) {
super('DNSCacheManager', 'DNSCachePanel', 'DNSCacheManager', testName);
let collectionPropServers = this.collectionProp('DNSCacheManager.servers');
let collectionPropHosts = this.collectionProp('DNSCacheManager.hosts');
super("DNSCacheManager", "DNSCachePanel", "DNSCacheManager", testName);
let collectionPropServers = this.collectionProp("DNSCacheManager.servers");
let collectionPropHosts = this.collectionProp("DNSCacheManager.hosts");
hosts.forEach(host => {
let elementProp = collectionPropHosts.elementProp(host.domain, 'StaticHost');
elementProp.stringProp('StaticHost.Name', host.domain);
elementProp.stringProp('StaticHost.Address', host.ip);
hosts.forEach((host) => {
let elementProp = collectionPropHosts.elementProp(
host.domain,
"StaticHost"
);
elementProp.stringProp("StaticHost.Name", host.domain);
elementProp.stringProp("StaticHost.Address", host.ip);
});
let boolProp = this.boolProp('DNSCacheManager.isCustomResolver', true);
let boolProp = this.boolProp("DNSCacheManager.isCustomResolver", true);
}
}
export class JDBCDataSource extends DefaultTestElement {
constructor(testName, datasource) {
super('JDBCDataSource', 'TestBeanGUI', 'JDBCDataSource', testName);
super("JDBCDataSource", "TestBeanGUI", "JDBCDataSource", testName);
this.boolProp('autocommit', true);
this.boolProp('keepAlive', true);
this.boolProp('preinit', false);
this.stringProp('dataSource', datasource.name);
this.stringProp('dbUrl', datasource.dbUrl);
this.stringProp('driver', datasource.driver);
this.stringProp('username', datasource.username);
this.stringProp('password', datasource.password);
this.stringProp('poolMax', datasource.poolMax);
this.stringProp('timeout', datasource.timeout);
this.stringProp('connectionAge', '5000');
this.stringProp('trimInterval', '60000');
this.stringProp('transactionIsolation', 'DEFAULT');
this.stringProp('checkQuery');
this.stringProp('initQuery');
this.stringProp('connectionProperties');
this.boolProp("autocommit", true);
this.boolProp("keepAlive", true);
this.boolProp("preinit", false);
this.stringProp("dataSource", datasource.name);
this.stringProp("dbUrl", datasource.dbUrl);
this.stringProp("driver", datasource.driver);
this.stringProp("username", datasource.username);
this.stringProp("password", datasource.password);
this.stringProp("poolMax", datasource.poolMax);
this.stringProp("timeout", datasource.timeout);
this.stringProp("connectionAge", "5000");
this.stringProp("trimInterval", "60000");
this.stringProp("transactionIsolation", "DEFAULT");
this.stringProp("checkQuery");
this.stringProp("initQuery");
this.stringProp("connectionProperties");
}
}
export class Arguments extends DefaultTestElement {
constructor(testName, args) {
super('Arguments', 'ArgumentsPanel', 'Arguments', testName);
super("Arguments", "ArgumentsPanel", "Arguments", testName);
this.args = args || [];
let collectionProp = this.collectionProp('Arguments.arguments');
let collectionProp = this.collectionProp("Arguments.arguments");
this.args.forEach(arg => {
if (arg.enable === true || arg.enable === undefined) { // 非禁用的条件加入执行
let elementProp = collectionProp.elementProp(arg.name, 'Argument');
elementProp.stringProp('Argument.name', arg.name);
elementProp.stringProp('Argument.value', arg.value);
elementProp.stringProp('Argument.desc', arg.desc);
elementProp.stringProp('Argument.metadata', arg.metadata, "=");
this.args.forEach((arg) => {
if (arg.enable === true || arg.enable === undefined) {
// 非禁用的条件加入执行
let elementProp = collectionProp.elementProp(arg.name, "Argument");
elementProp.stringProp("Argument.name", arg.name);
elementProp.stringProp("Argument.value", arg.value);
elementProp.stringProp("Argument.desc", arg.desc);
elementProp.stringProp("Argument.metadata", arg.metadata, "=");
}
});
}
@ -630,23 +783,24 @@ export class Arguments extends DefaultTestElement {
export class ElementArguments extends Element {
constructor(args, name, testName) {
super('elementProp', {
super("elementProp", {
name: name || "arguments",
elementType: "Arguments",
guiclass: "ArgumentsPanel",
testclass: "Arguments",
testname: testName || "",
enabled: "true"
enabled: "true",
});
let collectionProp = this.collectionProp('Arguments.arguments');
let collectionProp = this.collectionProp("Arguments.arguments");
if (args) {
args.forEach(arg => {
if (arg.enable === true || arg.enable === undefined) { // 非禁用的条件加入执行
let elementProp = collectionProp.elementProp(arg.name, 'Argument');
elementProp.stringProp('Argument.name', arg.name);
elementProp.stringProp('Argument.value', arg.value);
elementProp.stringProp('Argument.metadata', arg.metadata, "=");
args.forEach((arg) => {
if (arg.enable === true || arg.enable === undefined) {
// 非禁用的条件加入执行
let elementProp = collectionProp.elementProp(arg.name, "Argument");
elementProp.stringProp("Argument.name", arg.name);
elementProp.stringProp("Argument.value", arg.value);
elementProp.stringProp("Argument.metadata", arg.metadata, "=");
}
});
}
@ -655,35 +809,40 @@ export class ElementArguments extends Element {
export class RegexExtractor extends DefaultTestElement {
constructor(testName, props) {
super('RegexExtractor', 'RegexExtractorGui', 'RegexExtractor', testName);
this.props = props || {}
this.stringProp('RegexExtractor.useHeaders', props.headers);
this.stringProp('RegexExtractor.refname', props.name);
this.stringProp('RegexExtractor.regex', props.expression);
this.stringProp('RegexExtractor.template', props.template);
this.stringProp('RegexExtractor.default', props.default);
this.stringProp('RegexExtractor.match_number', props.match);
super("RegexExtractor", "RegexExtractorGui", "RegexExtractor", testName);
this.props = props || {};
this.stringProp("RegexExtractor.useHeaders", props.headers);
this.stringProp("RegexExtractor.refname", props.name);
this.stringProp("RegexExtractor.regex", props.expression);
this.stringProp("RegexExtractor.template", props.template);
this.stringProp("RegexExtractor.default", props.default);
this.stringProp("RegexExtractor.match_number", props.match);
}
}
export class JSONPostProcessor extends DefaultTestElement {
constructor(testName, props) {
super('JSONPostProcessor', 'JSONPostProcessorGui', 'JSONPostProcessor', testName);
this.props = props || {}
this.stringProp('JSONPostProcessor.referenceNames', props.name);
this.stringProp('JSONPostProcessor.jsonPathExprs', props.expression);
this.stringProp('JSONPostProcessor.match_numbers', props.match);
super(
"JSONPostProcessor",
"JSONPostProcessorGui",
"JSONPostProcessor",
testName
);
this.props = props || {};
this.stringProp("JSONPostProcessor.referenceNames", props.name);
this.stringProp("JSONPostProcessor.jsonPathExprs", props.expression);
this.stringProp("JSONPostProcessor.match_numbers", props.match);
}
}
export class XPath2Extractor extends DefaultTestElement {
constructor(testName, props) {
super('XPath2Extractor', 'XPath2ExtractorGui', 'XPath2Extractor', testName);
this.props = props || {}
this.stringProp('XPathExtractor2.default', props.default);
this.stringProp('XPathExtractor2.refname', props.name);
this.stringProp('XPathExtractor2.xpathQuery', props.expression);
this.stringProp('XPathExtractor2.namespaces', props.namespaces);
this.stringProp('XPathExtractor2.matchNumber', props.match);
super("XPath2Extractor", "XPath2ExtractorGui", "XPath2Extractor", testName);
this.props = props || {};
this.stringProp("XPathExtractor2.default", props.default);
this.stringProp("XPathExtractor2.refname", props.name);
this.stringProp("XPathExtractor2.xpathQuery", props.expression);
this.stringProp("XPathExtractor2.namespaces", props.namespaces);
this.stringProp("XPathExtractor2.matchNumber", props.match);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -58,6 +58,7 @@ public class DefinitionReference {
httpColumns.put("responseTimeout", "响应超时");
httpColumns.put("alias", "证书别名");
httpColumns.put("followRedirects", "跟随重定向");
httpColumns.put("autoRedirects", "自动重定向");
// http auth
authColumns.put("verification", "认证方式");
authColumns.put("username", "用户名");