在本节开始之前,我们在先要解决之前遗留的那个第三方table导致的一个bug:
就是多重列:
我们之前接口库中的解决方案是刷新页面绕过这个恶心的问题,但是步骤这里貌似不太适合刷新整个页面。所以只能面对。引起这个问题的原因是我们初始化这个表的时候,只初始化了tbody也就是内容部分,没有初始化thead表头部分.
所以我们给这俩个表的表头加上id,以便控制:(直接ctrl+F 搜索找到准确位置)
然后在我们的初始化清空步骤详情页的函数中加上这么几句:
红色圈部分代码:
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>';
现在这个多重列的问题就解决了。
让我们先看一看还剩下的任务:
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:
然后去views.py:
最后我们回到前端js,解析这个返回值,先输出一下看看对不对,
重启服务,刷新页面,试一下:
看来是成功了,每次选不同的接口,都可以打印出来这个接口最新的数据。
然后就是填充,关于填充的函数,我们也写过,就是打开步骤详情页时候运行的那段,我们直接复制过来,改一改成如下(注意,步骤名称和执行顺序不要改动)
整个函数的完整代码如下:
<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+"]").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>
好,让我们刷新页面测试一下:
- 首先我在接口库创建了一个接口,数据如下:
2.我再去用例库的一个大用例下创建了一个小步骤,新的小步骤如下:
3.我现在要套用接口库接口了:
可以看到,所有地方全都准确的显示上了。
然后我们点击保存发现可以保存成功。
但是等我们再次打开的时候发现了bug:
这个bug引起的原因应该是 加载的太慢导致,具体是我们初始化函数中,点击了一下none子标签,导致要显示这个不会携带 的文案刚准备显示出来的时候,系统瞬间切换到了form-data,所以这个文案还是偷偷的显示出来,没有被阻止。所以我们干脆不要点击none子标签了,多此一举了之前。:
再次打开的时候就发现没有了:
然后我们继续测试-多个接口来回套用,会有什么问题?
我们在接口库中再创建一个接口:
然后去 步骤详情页来回切换 这俩个接口:
切换到接口1的时候 ,一切正常。
然后切换到接口2的时候,bug出现。。
平白无故 多了三个空行出来。这恶心的第三方插件,果然不可靠,这里也给大家长了点经验,能自己写的,千万不要随便用网上的第三方的,因为真的我们很难去改正bug。
不过我这里暂时不换了,毕竟都已经深入的写了这么多的代码了,而且bug也解决的很多了,估计也就剩这最后一个了。全都是前端的js。大家如果对这觉得不想好好细抠的话,直接复制代码 和源码覆盖即可,没必要浪费大量精力在这学习解决第三方的控件bug。
我们在控制显示多少行的时候,貌似使用了自动点击新参数按钮,然后具体点击几次,有个计数。代码在这里:
也就是说,我们初始化了行数之后,根据真实数据一共有多少对,就点击多少次来做的。
看起来一点问题都没有,但是出现这么多空行,我觉得可能是点击一次,它新增了好多行。
经过实验,发现的确如此。
我只点击了一下,居然多出四五行~ 。看来我们除了要初始化 thead / tbody之外,也要初始化下这个新增参数按钮 才行。
但是考虑到 它的背后是第三方复杂的js函数,所以我们得去研究它背后的js函数:addBytton。
我们按住command 查看这个方法的调用关系:
我们点击一个进入到它原始js代码中:
发现进入了一个模式的庞大复杂的js文件中,以作者的功底,看起来也是比较吃力~
但是怎么调试呢?我们这里加一个console.log。看看点击一次按钮,调用了几次吧:
之后发现好的时候也就是一开始进入步骤详情页时候,点击是只执行一次:
然后我们切换不同的接口,出现bug时候再点击一次:
发现就很可怕了,居然每点击一次,就执行了三次这个函数!
所以我们只要想办法控制好,让他每点击一次就执行一遍即可,但是说起容易做起难。小伙伴们有其他方法的可以贡献一下这里的修改办法。
由于时间关系,这个bug的修改方法,下节课再分享哈~
欢迎持续关注哦~