在 index.html 中增加导出选项
<a href="#"><span class="topBtn J_exportContainer"><i class="uk-icon-save"></i>Export</span></a>
增加导出界面 exportPanel.js
var ExportPanel = React.createClass({
dealSave:function(){
var self = this,
userInput = React.findDOMNode(self.refs.pathInput).value;
self.props.onExportCollection && self.props.onExportCollection.call(null,userInput);
},
render:function(){
var self = this;
return (
<div>
<h4 className="subTitle">Export Postman collection</h4>
<div className="exportSection">
<div className="uk-form">
<input className="uk-form-large" ref="pathInput" defaultValue={self.props.defaultValue} type="text" width="300"/>
</div></div>
<div className="exportSection-btn">
<button type="button" className="uk-button" onClick={self.dealSave}>Save</button>
</div>
</div>
);
}
});
效果如图
在 index.js 中处理对保存按钮的处理
var exportBtn = $(".J_exportContainer");
exportBtn.on("click",function(e){
e.stopPropagation();
e.preventDefault();
$.getJSON("getRootPath",function(resObj){
var defaultPath = resObj.fullPath + "/default.postman_collection";
var ExportPanel = PopupContent["exportP"];
exportPanelEl = (<ExportPanel defaultValue = {defaultPath} onExportCollection={exportCollection} /> );
showPop({ left:"60%", content:exportPanelEl });
});
});
function exportCollection(userInput){
var data = {
type: 'export',
path: userInput,
data: showedIdSet
}
ws.send(data,function(){
hidePop();
});
}
这里是将录制的请求 id 都通过 websocket 发送给后端,后端去做导出请求的操作.我想让使用 filter 后只导出过滤后的请求,所以在 filter.js 中记录了录制的 id,代码很少就不贴了
新建 collection.js 和 request.js,用于保存集合和请求,websocketServer 根据 id 查询 db 中的信息,返回 request 信息并添加到 collection 中
if (jsonData.type == "export") {
var coll = new collection();
async.forEach(jsonData.data, function(item, callback) {
getRequestFromDB(item, coll.get().id, function(err, req) {
coll.addRequests(req.get().id, req.getJson());
callback();
});
}, function(err) {
var filePath = jsonData.path;
fs.writeFileSync(filePath, JSON.stringify(coll.getJson()));
});
}
生成返回值的验证代码
case '[object number]':
st.push('//检查 ' + key + ', 类型是number, p = ' + p + ', key = ' + key + '\n');
//检查存在该字段
st.push('assertHasData(jsonData' + p + ',"' + key + '");\n');
//检查字段类型是否符合
st.push('tests["jsonData' + p + '.' + key + ' = "+ Object.prototype.toString.call(jsonData' + p + '["' + key + '"]).toLowerCase()] = Object.prototype.toString.call(jsonData' + p + '["' + key + '"]).toLowerCase() == "[object number]";\n');
//检查数值相等
st.push('tests["jsonData' + p + '.' + key + ' = ' + data[key] + '"] = jsonData' + p + '["' + key + '"] === ' + data[key] + ';\r\n');
break;
我只验证的类型和值,如果想自定义,可修改 request 里的 parseToTestCode.至于 postman 脚本的格式,可在 postman 中导出查看文件格式
关于删除,是在表中新加了一列,代码可看源码,效果如图
生成的文件可导入 postman 使用或直接用 newman 执行
修改了 requestHandler.js,录制到请求后,根据请求执行 fuzz 的 case,为不影响客户端,只返回原请求的 response
var cases = fuzzer.generater.generate(options,userRule.shouldRunFuzzTest());
//get request body and route to local or remote
async.each(cases, function(item, callback) {
if (global.recorder) {
path = item.path;
resourceInfoId = global.recorder.appendRecord(resourceInfo);
resourceIdList.push(resourceInfoId);
item.resourceInfoId = resourceInfoId;
}
logUtil.printLog(color.green("\nreceived request to : " + host + path));
fetchReqData(function() {
routeReq(item, function() {
callback();
})
});
});
testCase 的格式如下,我只加了 11 条 case,如需要可在 fuzzer.js 中自定义
//no headers
var testCase1 = function(options) {
var testOptions = clone(options)
testOptions.description = "no headers";
testOptions.headers = {};
return testOptions;
}
添加支持参数"-F",为启动 fuzz 模式,详见 bin.js
整体改造完成,效果如下:
node lib/bin.js