公司使用 TAPD 作为项目、测试流程、测试用例、缺陷管理平台,而日常公司内部的交流工具为钉钉;TAPD 与钉钉无法在系统上进行很好的交互,在提交 bug 或者其他任务状态发生变化时,需要及时通知到相关的同事进行及时处理。
编写 Chrome 插件,对需要关注的任务、bug 进行状态监听;当状态发生流转时,能够通过插件调用钉钉机器人,及时的在工作群中通知到相关同事。
严重级别及以上、优先级为高及以上的 bug,状态流转至已解决的耗时由平均 4.8个小时提升至平均 2.9个小时。极大程度上提高了 bug 的解决效率和测试效率。
Chrome 插件编写 Java Script 对按钮进行监听,判断字段发生变化并且满足条件时,调用 XMLHttpRequest 对已设置好的钉钉群机器人发送消息,即可实现像上图一样的效果。是不是很 easy!
// var dingdingUrl = "https://oapi.dingtalk.com/robot/send?access_token=842de0b90ff76bfce0830ab71097dee74fad0a17ba0963a56a3fffa7a940449b";
$(function () {
isSend();
//提交缺陷
$('#_view').click(function () {
localStorage.setItem('preUrl', window.location.href);
});
//bug状态流转
$('#update_status_btn').click(function (){
localStorage.setItem('preUrl', window.location.href);
});
//从缓存拿上个页面地址进行对比,并进行发送
async function isSend() {
var _preUrl = localStorage.getItem('preUrl');
var _referrer = document.referrer;
if (_preUrl == _referrer) {
var _bugPriority = $('#ContentPriority').attr('data-editable-value');
var _bugSeverity = $('#ContentSeverity').attr('data-editable-value');
var _bugStatus = $('a[workflow-status-change=entityViewStatusChange]').attr('title');
//根据bug等级、状态、优先级决定是否进行发送钉钉
if(_bugSeverity == "致命" || _bugSeverity == "严重" || _bugPriority == "紧急" || _bugPriority == "高"){
if(_bugStatus != "已关闭" && _bugStatus != "接受/处理" ){
sendingMsg(await setBugParams())
}
}
localStorage.removeItem('preUrl');
}
}
async function setBugParams(){
var _bugUrl = getBugUrl(location.href);
var _bugTitle = $('#bug_title_view .editable-value').attr('title');
var _bugPriority = $('#ContentPriority').attr('data-editable-value');
var _bugSeverity = $('#ContentSeverity').attr('data-editable-value');
var _bugModule = $('#Content所属模块').attr('data-editable-value');
var _bugStatus = $('a[workflow-status-change=entityViewStatusChange]').attr('title');
var _bugOwners = $('#ContentCurrentOwner').text();
_bugOwners = _bugOwners.replace(/\(.*?\)/g,'');
var _bugPriority = $('#ContentPriority').attr('data-editable-value');
var _bugSeverity = $('#ContentSeverity').attr('data-editable-value');
var _mobileList =await getMobiles(_bugOwners);
var params = {
"msgtype": "text",
"text": {
"content": "BUG:" + _bugTitle +
"\n状态:" + _bugStatus +
"\n优先级:" + _bugPriority +
"\n级别:" + _bugSeverity +
"\n所属模块:" + _bugModule +
"\n链接:" + _bugUrl
},
"at":{
"atMobiles": _mobileList,
"isAtAll": false
}
};
return params;
}
//发送消息XMLHTTP
function sendingMsg(params) {
if (params == 0){
return;
}
var xhr = new XMLHttpRequest();
xhr.open("POST", dingdingUrl, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (window.Notification) {
chrome.extension.sendRequest({ type: 1, name: "发送钉钉通知", msg: xhr.responseText }, function (response) {
console.log(response);
});
} else { alert('消息已发送,当前浏览器不支持推送消息'); }
}
}
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(params));
}
//拼接bug URL
function getBugUrl(url){
var tmpList1 = splitStr(url,"?");
var tmpList2 = splitStr(tmpList1[1],"&");
var bugUrl = tmpList1[0] + "?";
for(var i=0;i<tmpList2.length;i++){
console.log(tmpList2[i]);
if(tmpList2[i].match("bug_id=")){
bugUrl = bugUrl + tmpList2[i];
break;
}
}
return bugUrl;
}
//获取处理人联系电话
async function getMobiles(bugOwners){
var mobileList = splitStr(bugOwners,";").filter((v) => v)
for(let i=0;i<mobileList.length;i++){
//后端封装了个简单的接口,用于获取通知人的电话
url='http://easytest.yzw.cn/user/getPhone?tapdUserAccount='+mobileList[i];
mobileList[i] = await getMobile(url);
}
return mobileList;
}
//单个获取电话号码
async function getMobile(url){
return await fetch(url).then(response=>response.text())
}
//字符串解析分割
function splitStr(str,regx){
var result = str.split(regx);
return result;
}
});
说明:本插件脚本中,封装了获取 TAPD 用户电话号码的接口,因为要实现在钉钉中 @ 到某一个人。TAPD 的用户名跟钉钉的电话号码是维护在一个表里头,用接口进行返回。如果不需要接口的方式,也可以简单的用 Map 的方式在脚本中维护即可;如果不需要实现 @ 到某个人,那么也可以不用获取电话号码。
脚本写好后,需要以插件的形式安装到 Chrome 中。以下介绍下整体插件文件目录以及安装过程:
## 安装步骤: