1. 修复bug:登录页
我的登录页面突然没了template_name,补上
2. 修复bug:表格多列
先要解决之前遗留的那个第三方table导致的一个bug:就是多重列:
之前接口库中的解决方案是刷新页面绕过这个恶心的问题,但是步骤这里貌似不太适合刷新整个页面。
原因是初始化表时只初始化了tbody也就是内容部分,没有初始化thead表头部分。给这俩个表的表头加上id,以便控制:
然后在初始化清空步骤详情页的函数中加上这么几句:
document.getElementById('mythead').innerHTML=' <tr>\n' +
' <td style="width: 30%">Key</td>\n' +
' <td style="width: 50%">Value</td>\n' +
' </tr>';
document.getElementById('mythead2').innerHTML=' <tr>\n' +
' <td style="width: 30%">Key</td>\n' +
' <td style="width: 50%">Value</td>\n' +
' </tr>';
现在这个多重列的问题就解决了。
3. 先看一看还剩下的任务:
4.步骤详情页的提取返回值功能
5.步骤详情页的断言返回值功能
7.步骤选择仓库接口生效
8.步骤的执行序号生效
9.用例实际执行的后台实现
10.报告的生成和保存
11.报告的展示
12.报告的word导出
13.步骤的mock功能
本节准备搞定 选择接口仓库接口的功能,之前做了这个下拉选框。当选择具体内容后,期望下面的各项输入框都跟着变,那就先找到这个选框的html源码:
注意,id是apis。
写一个监听类的js函数,监听这个select,只要内容变化,就触发下函数:
在红框内 ,要开始写上触发的动作代码了。这里触发后,唯一能获取到的就是这个select的value,就是最新选中的option的值:
这个值,也就是选中的接口库中接口的id。
拿到这个id,就可以跟后台找到这个接口的所有数据,然后填充到步骤详情页下面的各个输入框中,但是在这之前,要先清空一下这个步骤详情页内容,以免旧数据影响。
但是清空初始化步骤详情页的函数里,对这个select本身也进行了初始化,导致无论选什么接口,都会变成none,导致代码无法继续运行。联想到接口执行序号/名称/显示id等也都被删除了,所以重写一个这里专用的初始化函数。
所以代码如下:后面有完整该函数代码可复制。
上图中,增加了一层if判断,如果选的不是那个第一个值none才开始触发后续。
添加映射:
urls.py:
url(r'^step_get_api/$', step_get_api), # 步骤详情页获取接口数据
views.py:
# 步骤详情页获取接口数据
def step_get_api(request):
api_id = request.GET['api_id']
api = DB_apis.objects.filter(id=api_id).values()[0]
return HttpResponse(json.dumps(api), content_type='application/json')
回到前端js,解析这个返回值,先输出一下看看对不对。重启服务,刷新页面,试一下:
看来是成功了,每次选不同的接口,都可以打印出来这个接口最新的数据。
然后就是填充,关于填充的函数之前也写过,就是打开步骤详情页时候运行的那段,我们直接复制过来,改一改成如下(注意,步骤名称和执行顺序不要改动
此处会有一个小问题,就是接口返回的body_method是null,此处是none,因此这里要改下判断
// 请求体编码格式
if (ret.api_body_method === null || ret.api_body_method === 'null') {
$("li a[href=#none]")[0].click();
} else {
var body_method = '#'+ret.api_body_method;
$("li a[href="+body_method+"]")[0].click();
}
整个函数代码如下:
<script>
$(document).ready(function () {
$("#apis").change(function () {
//这里写只要触发后要执行的代码,就是把下面输入框全部填充的代码
document.getElementById('step_method').value = 'none';
document.getElementById('step_url').value = '';
document.getElementById('step_host').value = '';
document.getElementById('step_header').value='{}';
// 开始初始化请求体编码格式部分:
document.getElementById('mytbody').innerHTML='<tr><td></td><td></td></tr>';
document.getElementById('mytbody2').innerHTML='<tr><td></td><td></td></tr>';
document.getElementById('mythead').innerHTML=' <tr>\n' +
' <td style="width: 30%">Key</td>\n' +
' <td style="width: 50%">Value</td>\n' +
' </tr>';
document.getElementById('mythead2').innerHTML=' <tr>\n' +
' <td style="width: 30%">Key</td>\n' +
' <td style="width: 50%">Value</td>\n' +
' </tr>';
document.getElementById('raw_Text').value = '';
document.getElementById('raw_JavaScript').value = '';
document.getElementById('raw_Json').value = '';
document.getElementById('raw_Html').value = '';
document.getElementById('raw_Xml').value = '';
// 运行第三方表格插件的函数:
$('#mytable').SetEditable({
$addButton: $('#add'),
});
$('#mytable2').SetEditable({
$addButton: $('#add2'),
});
if($("#apis").val() !== 'none'){ // 判断不是第一个请选择,那就去获取接口信息
$.get("/step_get_api/",{
"api_id":$("#apis").val()
},function (ret) {
//拿到数据开始填充
console.log(ret)
var ret = eval(ret);
console.log(ret);
document.getElementById('step_method').value = ret.api_method;
document.getElementById('step_url').value = ret.api_url;
document.getElementById('step_host').value = ret.api_host;
document.getElementById('step_header').value = ret.api_header;
// 请求体编码格式
var body_method = '#'+ret.body_method;
$("li a[href="+body_method+"]")[0].click();
// 请求体显示
if(ret.body_method === 'Text'){
document.getElementById('raw_Text').value = ret.api_body;
}
if(ret.body_method === 'JavaScript'){
document.getElementById('raw_JavaScript').value = ret.api_body;
}
if(ret.body_method === 'Json'){
document.getElementById('raw_Json').value = ret.api_body;
}
if(ret.body_method === 'Html'){
document.getElementById('raw_Html').value = ret.api_body;
}
if(ret.body_method === 'Xml'){
document.getElementById('raw_Xml').value = ret.api_body;
}
if(ret.body_method === 'form-data'){
var tbody = document.getElementById('mytbody'); // 定位表格中的tbody部分
body = eval(ret.api_body); //把这个像列表的字符串请求体变成真正的列表
for(var i=0;i<body.length;i++){ // 遍历这个请求体列表
key = body[i][0]; //拿出每一个键值对的key
value = body[i][1];//拿出每一个键值对的value
var childs_tr = tbody.children ;//获取到这个表格下面所有的tr组成的大列表
// 每个tr下的children得到的是 td列表,只有俩个。
childs_tr[i].children[0].innerText = key; //第一个td放key
childs_tr[i].children[1].innerText = value;//第二个td放value
//判断是否是最后一次遍历,来决定是否点击新增参数按钮
if(i<body.length-1){
document.getElementById('add').click()
}
}
}
if(ret.body_method === 'x-www-form-urlencoded'){
var tbody = document.getElementById('mytbody2'); // 定位表格中的tbody部分
body = eval(ret.api_body); //把这个像列表的字符串请求体变成真正的列表
for(var i=0;i<body.length;i++){ // 遍历这个请求体列表
key = body[i][0]; //拿出每一个键值对的key
value = body[i][1];//拿出每一个键值对的value
var childs_tr = tbody.children ;//获取到这个表格下面所有的tr组成的大列表
// 每个tr下的children得到的是 td列表,只有俩个。
childs_tr[i].children[0].innerText = key; //第一个td放key
childs_tr[i].children[1].innerText = value;//第二个td放value
//判断是否是最后一次遍历,来决定是否点击新增参数按钮
if(i<body.length-1){
document.getElementById('add2').click()
}
}
}
})
}
});
});
</script>
刷新页面,看看效果:
看着很正常,但保存后打开,就多了一块东西
这个bug引起的原因应该是 加载的太慢导致,具体是初始化函数中,点击了一下none子标签,导致要显示这个不会携带 的文案刚准备显示出来的时候,系统瞬间切换到了form-data,所以这个文案还是偷偷的显示出来,没有被阻止。所以干脆不要点击none子标签了,多此一举了之前:
删掉后,刷新页面:
然后继续测试-多个接口来回套用,会有什么问题?
4. 修复bug:表格多行
在控制显示多少行的时候,貌似使用了自动点击新参数按钮,然后具体点击几次,有个计数。也就是说,初始化了行数之后,根据真实数据一共有多少对,就点击多少次来做的。
看起来一点问题都没有,但是出现这么多空行,可能是点击一次,它新增了好多行。经过实验,发现的确如此。
切换接口,再切回来,自动多了好几行
只点击了一下,居然多出四五行~ 。看来我们除了要初始化 thead / tbody之外,也要初始化下这个新增参数按钮 才行。
但是考虑到 它的背后是第三方复杂的js函数,所以我们得去研究它背后的js函数:addBytton。
按住command 查看这个方法的调用关系:
点击一个进入到它原始js代码中,但对于笔者很吃力,因此要换个方式。
但是怎么调试呢?这里加一个console.log。看看点击一次按钮,调用了几次吧:
之后发现好的时候也就是一开始进入步骤详情页时候,点击是只执行一次:
然后切换不同的接口,出现bug时候再点击一次:
发现就很可怕了,居然每点击一次,就执行了三次这个函数!所以只要想办法控制好,让他每点击一次就执行一遍即可,但是说起容易做起难。有其他方法的可以贡献一下这里的修改办法。
由于时间关系,这个bug的修改方法,下节课再分享哈~