提交 082e6164 编写于 作者: 泰斯特Test's avatar 泰斯特Test

Merge remote-tracking branch 'remotes/origin/master' into dev

# Conflicts:
#	.idea/misc.xml
#	.idea/workspace.xml
#	dist/index.html
#	dist/static/js/manifest.2ae2e69a05c33dfc65f8.js.map
#	frontend/package.json
#	frontend/src/views/Home.vue
#	frontend/src/views/Project.vue
......@@ -4,6 +4,12 @@
![泰斯特平台LOGO.png](https://github.com/amazingTest/Taisite-Platform/blob/master/images/泰斯特平台LOGO.png)
## 开源申明
**这是一个受限制的自由软件!您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途;也不允许对程序代码修改后以任何形式任何目的的再发布。**
**为尊重作者的劳动成果,Taisite-Platform 关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论。 QQ:523314409 泰斯特**
## Ⅰ. 泰斯特平台简介
### 背景
......@@ -26,12 +32,6 @@
**推荐使用 Chrome 最新浏览器使用~**
### 开源协议
***APGL-3.0***
(详细内容请查阅 LICENSE 文件)
## Ⅱ. 泰斯特平台特点 (os:和其他测试平台有什么区别?)
**0. 已经投入生产环境使用 1 年以上, 用起来轻松没负担~**
......
......@@ -95,11 +95,13 @@ def update_case_suite(project_id, case_suite_id):
filtered_data = CaseSuite.filter_field(request.get_json())
for key, value in filtered_data.items():
CaseSuite.update({"_id": ObjectId(case_suite_id)},
{'$set': {key: value}})
{'$set': {key: value}})
update_response = CaseSuite.update({"_id": ObjectId(case_suite_id)},
{'$set': {'lastUpdateTime': datetime.datetime.utcnow()}}, )
{'$set': {'lastUpdateTime': datetime.datetime.utcnow()}},)
if update_response["n"] == 0:
return jsonify({'status': 'failed', 'data': '未找到相应更新数据!'})
return jsonify({'status': 'ok', 'data': '更新成功'})
except BaseException as e:
return jsonify({'status': 'failed', 'data': '更新失败: %s' % e})
......@@ -49,6 +49,9 @@ def add_cron(project_id):
is_ding_ding_notify=filtered_data.get('isDingDingNotify'),
ding_ding_access_token=filtered_data.get('dingdingAccessToken'),
ding_ding_notify_strategy=filtered_data.get('dingdingNotifyStrategy'),
is_enterprise_wechat_notify=filtered_data.get('isEnterpriseWechatNotify'),
enterprise_wechat_access_token=filtered_data.get('enterpriseWechatAccessToken'),
enterprise_wechat_notify_strategy=filtered_data.get('enterpriseWechatNotifyStrategy'),
trigger_type=filtered_data.get('triggerType'),
test_case_id_list=filtered_data.get('testCaseIdList'),
is_execute_forbiddened_case=filtered_data.get('isExecuteForbiddenedCase'),
......@@ -60,6 +63,9 @@ def add_cron(project_id):
is_ding_ding_notify=filtered_data.get('isDingDingNotify'),
ding_ding_access_token=filtered_data.get('dingdingAccessToken'),
ding_ding_notify_strategy=filtered_data.get('dingdingNotifyStrategy'),
is_enterprise_wechat_notify=filtered_data.get('isEnterpriseWechatNotify'),
enterprise_wechat_access_token=filtered_data.get('enterpriseWechatAccessToken'),
enterprise_wechat_notify_strategy=filtered_data.get('enterpriseWechatNotifyStrategy'),
trigger_type=filtered_data.get('triggerType'),
test_case_id_list=filtered_data.get('testCaseIdList'),
is_execute_forbiddened_case=filtered_data.get('isExecuteForbiddenedCase'),
......
......@@ -46,9 +46,11 @@ def update_project(project_id):
Project.update({"_id": ObjectId(project_id)},
{'$set': {key: value}})
update_response = Project.update({"_id": ObjectId(project_id)},
{'$set': {'lastUpdateTime': datetime.datetime.utcnow()}}, )
{'$set': {'lastUpdateTime': datetime.datetime.utcnow()}},)
if update_response["n"] == 0:
return jsonify({'status': 'failed', 'data': '未找到相应更新数据!'})
return jsonify({'status': 'ok', 'data': '更新成功'})
except BaseException as e:
return jsonify({'status': 'failed', 'data': '更新失败: %s' % e})
......@@ -97,7 +97,7 @@ def update_case(project_id, case_suite_id, case_id):
TestingCase.update({"_id": ObjectId(case_id)},
{'$set': {key: value}})
update_response = TestingCase.update({"_id": ObjectId(case_id)},
{'$set': {'lastUpdateTime': datetime.datetime.utcnow()}})
{'$set': {'lastUpdateTime': datetime.datetime.utcnow()}})
if update_response["n"] == 0:
return jsonify({'status': 'failed', 'data': '未找到相应更新数据!'})
return jsonify({'status': 'ok', 'data': '更新成功'})
......@@ -163,8 +163,7 @@ def start_test():
return jsonify({'status': 'failed', 'data': '未在「测试用例」中找到任何「启用的」接口测试用例'})
testing_cases = copy.deepcopy(TestingCase.find({'isDeleted': {'$ne': True}, 'status': True}) # sort吃顺序
.sort(
[('caseSuiteId', pymongo.ASCENDING), ('createAt', pymongo.ASCENDING)])) # 再次初始化 Cursor object
.sort([('caseSuiteId', pymongo.ASCENDING), ('createAt', pymongo.ASCENDING)])) # 再次初始化 Cursor object
if case_id_list:
for testing_case in testing_cases:
if str(testing_case["_id"]) in case_id_list:
......@@ -195,8 +194,7 @@ def start_test():
if not is_single_test:
try:
tester.execute_all_test_and_send_report(TestingCase, TestReport, project_id, executor_nick_name,
execution_mode)
tester.execute_all_test_and_send_report(TestingCase, TestReport, project_id, executor_nick_name, execution_mode)
return jsonify({'status': 'ok', 'data': '测试已启动,稍后请留意自动化测试报告'})
except BaseException as e:
return jsonify({'status': 'failed', 'data': '测试启动失败: %s' % e})
......@@ -253,29 +251,29 @@ def single_test_result(case_id):
test_case_map = {
'caseSuiteId': '用例组_id',
'caseSuiteName': '用例组名称',
'_id': '用例_id',
'name': '用例名称',
'description': '用例描述',
'testCaseType': '用例类型',
'requestProtocol': '请求协议',
'requestMethod': '请求方法',
'domain': '请求域名',
'route': '请求路由',
'headers': '请求头部',
'presendParams': '请求参数',
'checkHttpCode': '状态码校验',
'checkResponseData': '正则校验',
'checkResponseSimilarity': '文本相似度校验',
'checkResponseNumber': '数值校验',
'setGlobalVars': '设置全局变量',
'isClearCookie': '请求前是否清除Cookie',
'createAt': '创建时间/UTC',
'creatorNickName': '创建人',
'lastUpdateTime': '最后更新时间/UTC',
'lastUpdatorNickName': '最后更新人',
}
'caseSuiteId': '用例组_id',
'caseSuiteName': '用例组名称',
'_id': '用例_id',
'name': '用例名称',
'description': '用例描述',
'testCaseType': '用例类型',
'requestProtocol': '请求协议',
'requestMethod': '请求方法',
'domain': '请求域名',
'route': '请求路由',
'headers': '请求头部',
'presendParams': '请求参数',
'checkHttpCode': '状态码校验',
'checkResponseData': '正则校验',
'checkResponseSimilarity': '文本相似度校验',
'checkResponseNumber': '数值校验',
'setGlobalVars': '设置全局变量',
'isClearCookie': '请求前是否清除Cookie',
'createAt': '创建时间/UTC',
'creatorNickName': '创建人',
'lastUpdateTime': '最后更新时间/UTC',
'lastUpdatorNickName': '最后更新人',
}
@app.route("/api/importTestCases", methods=['POST'])
......@@ -315,8 +313,7 @@ def import_test_cases():
missing_attributes = [nip for nip in non_intersection if nip in test_case_map.values()]
return jsonify({'status': 'failed', 'data': '「测试用例」Sheet 表头缺失字段: %s' % missing_attributes}) \
if missing_attributes else jsonify({'status': 'failed', 'data': '「测试用例」Sheet 表头存在多余字段: %s' %
[nip for nip in non_intersection if
nip not in test_case_map.values()]})
[nip for nip in non_intersection if nip not in test_case_map.values()]})
attributes_indexes = [test_case_attributes.index(v) for v in test_case_map.values()]
......@@ -334,8 +331,8 @@ def import_test_cases():
for j, v in enumerate(test_case_info.keys()):
test_case_info[v] = test_case_table.row_values(i + 1)[attributes_indexes[j]]
try:
is_case_exist, pre_import_case_info, is_case_suite_exist \
= get_pre_import_case_info(test_case_info, test_case_mapping=test_case_map, table_row_index=(i + 2))
is_case_exist, pre_import_case_info, is_case_suite_exist\
= get_pre_import_case_info(test_case_info, test_case_mapping=test_case_map, table_row_index=(i+2))
except BaseException as b_e:
return jsonify({'status': 'failed', 'data': '导入数据异常: %s' % b_e})
......@@ -346,7 +343,7 @@ def import_test_cases():
pre_import_case_info = TestingCase.filter_field(pre_import_case_info, use_set_default=False)
result = str(TestingCase.update({"_id": ObjectId(pre_import_case_info.get('_id'))},
{'$set': pre_import_case_info})) + \
' _id: {}'.format(pre_import_case_info.get('_id'))
' _id: {}'.format(pre_import_case_info.get('_id'))
update_count += 1
else:
try:
......@@ -364,13 +361,13 @@ def import_test_cases():
# 在用例列表内导入
else:
inserted_case_suite_id = None
case_suite_name = pre_import_case_info.get('caseSuiteName') \
case_suite_name = pre_import_case_info.get('caseSuiteName')\
if pre_import_case_info.get('caseSuiteName') else ''
if is_case_suite_exist:
if not case_suite_name == CaseSuite.find_one(
{"_id": ObjectId(pre_import_case_info.get('caseSuiteId'))})['name']:
CaseSuite.update({"_id": ObjectId(pre_import_case_info.get('caseSuiteId'))},
{'$set': {'name': case_suite_name}})
{'$set': {'name': case_suite_name}})
else:
pass
else:
......@@ -396,8 +393,8 @@ def import_test_cases():
if is_case_exist:
pre_import_case_info = TestingCase.filter_field(pre_import_case_info, use_set_default=False)
result = str(TestingCase.update({"_id": ObjectId(pre_import_case_info.get('_id'))},
{'$set': pre_import_case_info})) + ' _id: {}' \
.format(pre_import_case_info.get('_id'))
{'$set': pre_import_case_info})) + ' _id: {}'\
.format(pre_import_case_info.get('_id'))
update_count += 1
else:
......@@ -468,7 +465,7 @@ def export_test_cases():
elif isinstance(case.get(key), datetime.datetime):
case_data = str(case.get(key)).replace('.', ':', 1) \
if common.can_convert_to_str(case.get(key)) \
and str(case.get(key)).count('.') < 2 else str(case.get(key))
and str(case.get(key)).count('.') < 2 else str(case.get(key))
else:
case_data = str(case.get(key)) if case.get(key) is not None else ''
export_case.append(case_data)
......@@ -484,7 +481,7 @@ def export_test_cases():
print(e)
return _case_info
export_testing_cases = map(export_case_format, map(add_case_suite_name, TestingCase.find(query)))
export_testing_cases = map(export_case_format, map(add_case_suite_name, TestingCase.find(query)))
bytes_io = BytesIO()
workbook = xlsxwriter.Workbook(bytes_io, {'in_memory': True})
......@@ -501,3 +498,9 @@ def export_test_cases():
bytes_io.seek(0)
return send_file(bytes_io, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
......@@ -20,19 +20,26 @@ def on_exec_test(data):
except BaseException:
raise TypeError('参数 「testDomain」 不合法')
try:
data['dingdingAccessToken'] = data['dingdingAccessToken'].strip()
except BaseException:
raise TypeError('参数 「dingdingAccessToken」 不合法')
data['isExecuteForbiddenedCase'] = True if common.can_convert_to_str(data.get('isExecuteForbiddenedCase'))\
data['isExecuteForbiddenedCase'] = True if data.get('isExecuteForbiddenedCase') \
and common.can_convert_to_str(data.get('isExecuteForbiddenedCase'))\
and data.get('isExecuteForbiddenedCase').upper() == 'TRUE' else False
data['isDingDingNotify'] = True if common.can_convert_to_str(data.get('isDingDingNotify'))\
and data.get('isDingDingNotify').upper() == 'TRUE' else False
data['isDingDingNotify'] = True if data.get('isDingDingNotify')\
and common.can_convert_to_str(data.get('isDingDingNotify'))\
and data.get('isDingDingNotify').upper() == 'TRUE' else False
data['isEnterpriseWechatNotify'] = True if data.get('isEnterpriseWechatNotify')\
and common.can_convert_to_str(data.get('isEnterpriseWechatNotify')) \
and data.get('isEnterpriseWechatNotify').upper() == 'TRUE' else False
data['dingdingAccessToken'] = data.get('dingdingAccessToken').strip() if data.get('dingdingAccessToken')\
and common.can_convert_to_str(data.get('dingdingAccessToken')) else None
data['enterpriseWechatAccessToken'] = data.get('enterpriseWechatAccessToken').strip()\
if data.get('enterpriseWechatAccessToken') and common.can_convert_to_str(data.get('enterpriseWechatAccessToken')) else None
try:
data['alarmMailList'] = data['alarmMailList'].strip().split(';')
data['alarmMailList'] = data['alarmMailList'].strip().split(';') if data.get('alarmMailList') else []
except BaseException:
raise TypeError('参数 「alarmMailList」 不合法')
......@@ -49,6 +56,8 @@ def on_exec_test(data):
run_date=filtered_data.get('runDate'),
is_ding_ding_notify=filtered_data.get('isDingDingNotify'),
ding_ding_access_token=filtered_data.get('dingdingAccessToken'),
is_enterprise_wechat_notify=filtered_data.get('isEnterpriseWechatNotify'),
enterprise_wechat_access_token=filtered_data.get('enterpriseWechatAccessToken'),
is_web_hook=True)
cron_manager.add_cron(cron)
......@@ -29,6 +29,28 @@ class CronTab(Model):
interval = FloatField()
runDate = DateField()
alarmMailList = ArrayField()
isDingDingNotify = BooleanField(field_name='isDingDingNotify', default=False)
dingdingAccessToken = StringField()
dingdingNotifyStrategy = DictField(field_name='dingdingNotifyStrategy',
default={'success': True, 'fail': True},
expected_structure={
'expectedTypeRange': [dict],
'expectedDict': {
'success': {'expectedTypeRange': [bool]},
'fail': {'expectedTypeRange': [bool]}
}
})
isEnterpriseWechatNotify = BooleanField(field_name='isEnterpriseWechatNotify', default=False)
enterpriseWechatAccessToken = StringField()
enterpriseWechatNotifyStrategy = DictField(field_name='enterpriseWechatNotifyStrategy',
default={'success': True, 'fail': True},
expected_structure={
'expectedTypeRange': [dict],
'expectedDict': {
'success': {'expectedTypeRange': [bool]},
'fail': {'expectedTypeRange': [bool]}
}
})
status = StringField(field_name='status', default='CREATED')
createAt = DateField()
creatorNickName = StringField()
......
......@@ -148,7 +148,7 @@ class tester:
for key, value in test_case['presendParams'].items():
if value is not None:
get_method_params_value = common.resolve_global_var(pre_resolve_var=value,
global_var_dic=self.global_vars)\
global_var_dic=self.global_vars) \
if isinstance(value, str) else value
url += '%s=%s&' % (key, get_method_params_value)
url = url[0:(len(url) - 1)]
......
......@@ -95,6 +95,9 @@ class CronManager:
is_ding_ding_notify = cron_info.get('isDingDingNotify')
ding_ding_access_token = cron_info.get('dingdingAccessToken')
ding_ding_notify_strategy = cron_info.get('dingdingNotifyStrategy')
is_enterprise_wechat_notify = cron_info.get('isEnterpriseWechatNotify')
enterprise_wechat_access_token = cron_info.get('enterpriseWechatAccessToken')
enterprise_wechat_notify_strategy = cron_info.get('enterpriseWechatNotifyStrategy')
try:
if trigger_type == 'interval' and int(interval) > 0:
......@@ -112,6 +115,9 @@ class CronManager:
is_ding_ding_notify=is_ding_ding_notify,
ding_ding_access_token=ding_ding_access_token,
ding_ding_notify_strategy=ding_ding_notify_strategy,
is_enterprise_wechat_notify=is_enterprise_wechat_notify,
enterprise_wechat_access_token=enterprise_wechat_access_token,
enterprise_wechat_notify_strategy=enterprise_wechat_notify_strategy,
trigger_type=trigger_type, # 更新定时器时,此参数并没有真正起到作用, 仅修改展示字段
test_case_id_list=test_case_id_list,
run_date=run_date) # 更新定时器时,此参数并没有起到作用, 仅修改展示字段
......@@ -123,6 +129,9 @@ class CronManager:
is_ding_ding_notify=is_ding_ding_notify,
ding_ding_access_token=ding_ding_access_token,
ding_ding_notify_strategy=ding_ding_notify_strategy,
is_enterprise_wechat_notify=is_enterprise_wechat_notify,
enterprise_wechat_access_token=enterprise_wechat_access_token,
enterprise_wechat_notify_strategy=enterprise_wechat_notify_strategy,
trigger_type=trigger_type, # 更新定时器时,此参数并没有起到作用, 仅修改展示字段
test_case_id_list=test_case_id_list,
seconds=interval) # 更新定时器时,此参数并没有起到作用, 仅修改展示字段
......
......@@ -13,7 +13,8 @@ import requests
class Cron:
def __init__(self, test_case_suite_id_list, test_domain, trigger_type, is_execute_forbiddened_case=False,
test_case_id_list=None, alarm_mail_list=None, is_ding_ding_notify=False, ding_ding_access_token=None,
ding_ding_notify_strategy=None, is_web_hook=False, **trigger_args):
ding_ding_notify_strategy=None, is_enterprise_wechat_notify=False, enterprise_wechat_access_token=None,
enterprise_wechat_notify_strategy=None, is_web_hook=False, **trigger_args):
if test_case_id_list is None:
test_case_id_list = []
......@@ -42,8 +43,10 @@ class Cron:
self.ding_ding_notify_strategy = {'success': True, 'fail': True}\
if is_ding_ding_notify and ding_ding_notify_strategy is None else ding_ding_notify_strategy
# print('self.ding_ding_access_token ----> %s' % self.ding_ding_access_token)
# print('self.ding_ding_notify_strategy ----> %s' % self.ding_ding_notify_strategy)
self.enterprise_wechat_access_token = enterprise_wechat_access_token if enterprise_wechat_access_token else None
self.enterprise_wechat_notify_strategy = {'success': True, 'fail': True} \
if is_enterprise_wechat_notify and enterprise_wechat_notify_strategy is None\
else enterprise_wechat_notify_strategy
self._id = str(common.get_object_id())
self.alarm_mail_list = []
......@@ -138,9 +141,13 @@ class Cron:
res = requests.post(url=hook_url, json=data, headers=headers)
return res
# TODO 当webhook模式触发cron时,可选测试结果发送微信群
def send_wechat_notify(self, hook_url, message):
pass
def send_enterprise_wechat_notify(self, title, content, headers=None):
if headers is None:
headers = {'Content-Type': 'application/json'}
hook_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={}".format(self.enterprise_wechat_access_token)
data = {"msgtype": "markdown", "markdown": {"content": "{} \n >{}".format(title, content)}}
res = requests.post(url=hook_url, json=data, headers=headers)
return res
# TODO 发送报告具体链接至邮箱。 如interfaceTestProject/5ccfa182b144f831b04d7ca5/projectReport
def send_report_to_staff(self, project_id, mail_list, mail_title, mail_content):
......@@ -180,6 +187,26 @@ class Cron:
is_send_mail = self.failed_count > 0 and isinstance(self.alarm_mail_list, list)\
and len(self.alarm_mail_list) > 0
is_send_ding_ding = self.ding_ding_access_token if hasattr(self, 'ding_ding_access_token') else False
is_send_enterprise_wechat = self.enterprise_wechat_access_token if hasattr(self, 'enterprise_wechat_access_token')\
else False
if is_send_enterprise_wechat:
enterprise_wechat_title = '智能测试平台企业微信服务'
enterprise_wechat_content = '泰斯特平台 \n >⛔ 测试失败 \n > 生成报告id: {}'.format(self.report_id) \
if self.failed_count > 0 else '泰斯特平台 \n >👍️️️️ 测试通过 \n > 生成报告id: {}' \
.format(self.report_id)
if hasattr(self, 'enterprise_wechat_notify_strategy') and self.enterprise_wechat_notify_strategy.get('fail') \
and self.failed_count > 0:
enterprise_wechat_res = self.send_enterprise_wechat_notify(title=enterprise_wechat_title, content=enterprise_wechat_content)
if not enterprise_wechat_res.status_code == 200:
raise BaseException('企业微信发送异常: {}'.format(enterprise_wechat_res.text))
if hasattr(self, 'enterprise_wechat_notify_strategy') and self.enterprise_wechat_notify_strategy.get('success') \
and self.failed_count <= 0:
enterprise_wechat_res = self.send_enterprise_wechat_notify(title=enterprise_wechat_title, content=enterprise_wechat_content)
if not enterprise_wechat_res.status_code == 200:
raise BaseException('企业微信发送异常: {}'.format(enterprise_wechat_res.text))
if is_send_ding_ding:
dingding_title = '智能测试平台钉钉服务'
dingding_content = '### ⛔️ 泰斯特平台 \n >⛔ 测试失败 \n > 生成报告id: {}'.format(self.report_id)\
......@@ -195,6 +222,7 @@ class Cron:
dingding_res = self.send_ding_ding_notify(title=dingding_title, content=dingding_content)
if not dingding_res.status_code == 200:
raise BaseException('钉钉发送异常: {}'.format(dingding_res.text))
if is_send_mail:
mesg_title = '测试平台告警'
mesg_content = "Dears: \n\n 定时测试中存在用例未通过!,请登录平台查看详情 !\n\n 报告编号为:" \
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
因为 它太大了无法显示 source diff 。你可以改为 查看blob
此差异已折叠。
此差异已折叠。
因为 它太大了无法显示 source diff 。你可以改为 查看blob
此差异已折叠。
......@@ -85,7 +85,7 @@
"vuex": "^3.1.0",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^3.3.2",
"webpack-dev-server": "^2.9.7",
"webpack-dev-server": "^3.1.11",
"webpack-hot-middleware": "^2.22.3",
"webpack-merge": "^4.1.0"
},
......@@ -156,9 +156,10 @@
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack": "^3.12.0",
"webpack-bundle-analyzer": "^3.3.2",
"webpack-dev-server": "^2.9.7",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.1.11",
"webpack-merge": "^4.1.0"
},
"engines": {
......
......@@ -4,46 +4,25 @@
</br>
</br>
<div style="font-size:20px; text-align: center;">
我,泰斯特,软件测试、机器学习爱好者。致力于将人工智能与自动化测试有效结合,让软件测试更具智能化。
</div>
</br>
</br>
</br>
<div align="center">
<img src="../assets/imgs/i-am-strong.jpg">
</img>
我,泰斯特,软件测试、机器学习爱好者。致力于将人工智能与自动化测试有效结合,让软件测试更具智能化。
</div>
</br>
</br>
</br>
<div style="font-size:20px; text-align: center;">
若您想在自动化测试上更近一步,欢迎扫描下方海报二维码、泰斯特带你成长~
恭喜你成功部署了超好用的泰斯特平台~
</div>
</br>
</br>
</br>
<div align="center">
<img src="../assets/imgs/planetPoster.jpg">
</img>
</div>
</br>
</br>
</br>
<div style="font-size:20px; text-align: center;">
若您对「泰斯特平台」有任何吐槽或想对平台有更深入的了解,欢迎扫描下方二维码关注我并了解最新资讯。
</div>
</br>
</br>
</br>
<div align="center">
<img src="../assets/imgs/publicAcount.jpg">
</img>
<div style="font-size:25px; text-align: center;">
<a target="_blank" style="color: #ff9e1b" href="https://shimo.im/docs/8TqxG3Ttjvj9yT8T" >点我了解泰斯特平台如何使用</a>
</div>
</br>
</br>
</br>
<div style="font-size:20px; text-align: center;">
若您觉得「泰斯特平台」使用起来非常顺心,舒服,那么也希望您能为开源项目的维护迭代尽一份绵薄之力~
若您觉得「泰斯特平台」使用起来非常顺心,舒服,希望他变得更好用,那么也希望您能为开源项目的维护迭代尽一份绵薄之力~
</div>
</br>
</br>
......
......@@ -116,6 +116,80 @@
</div>
</transition>
<el-form-item label="钉钉提醒">
<el-radio
v-model="editForm.isDingDingNotify"
:label="true">
</el-radio>
<el-radio
v-model="editForm.isDingDingNotify"
:label="false">
</el-radio>
</el-form-item>
<transition name="el-zoom-in-top">
<div
class="form-item-sub form-item-short"
v-if="editForm.isDingDingNotify && editForm.isDingDingNotify.toString()==='true'">
<el-form-item
style="width:90%"
label="钉钉Token"
prop="dingdingAccessToken">
<el-input placeholder="如: 52597c9b583090fd397493626c035064f03aaf92669f032d215fde67e43a807e" v-model.trim="editForm.dingdingAccessToken" auto-complete="off"></el-input>
</el-form-item>
<el-form-item v-show="editForm.isDingDingNotify.toString()==='true'" label="提醒策略">
<el-checkbox
v-model="editForm.dingdingNotifyStrategy.success"
label="测试全通过时提醒">
</el-checkbox>
<el-checkbox
v-model="editForm.dingdingNotifyStrategy.fail"
label="测试存在失败时提醒">
</el-checkbox>
</el-form-item>
</div>
</transition>
<el-form-item label="企微提醒">
<el-radio
v-model="editForm.isEnterpriseWechatNotify"
:label="true">
</el-radio>
<el-radio
v-model="editForm.isEnterpriseWechatNotify"
:label="false">
</el-radio>
</el-form-item>
<transition name="el-zoom-in-top">
<div
class="form-item-sub form-item-short"
v-if="editForm.isEnterpriseWechatNotify && editForm.isEnterpriseWechatNotify.toString()==='true'">
<el-form-item
style="width:90%"
label="企微Token"
prop="enterpriseWechatAccessToken">
<el-input placeholder="如: 618311c0-yd0f-37e0-b11d-9f7c521d8gb9" v-model.trim="editForm.enterpriseWechatAccessToken" auto-complete="off"></el-input>
</el-form-item>
<el-form-item v-show="editForm.isEnterpriseWechatNotify.toString()==='true'" label="提醒策略">
<el-checkbox
v-model="editForm.enterpriseWechatNotifyStrategy.success"
label="测试全通过时提醒">
</el-checkbox>
<el-checkbox
v-model="editForm.enterpriseWechatNotifyStrategy.fail"
label="测试存在失败时提醒">
</el-checkbox>
</el-form-item>
</div>
</transition>
<el-form-item label="告警邮箱" prop="alarmMailList">
<el-select
style="width: 60%;"
......@@ -184,6 +258,80 @@
</div>
</transition>
<el-form-item label="钉钉提醒">
<el-radio
v-model="addForm.isDingDingNotify"
:label="true">
</el-radio>
<el-radio
v-model="addForm.isDingDingNotify"
:label="false">
</el-radio>
</el-form-item>
<transition name="el-zoom-in-top">
<div
class="form-item-sub form-item-short"
v-if="addForm.isDingDingNotify && addForm.isDingDingNotify.toString()==='true'">
<el-form-item
style="width:90%"
label="钉钉Token"
prop="dingdingAccessToken">
<el-input placeholder="如: 52597c9b583090fd397493626c035064f03aaf92669f032d215fde67e43a807e" v-model.trim="addForm.dingdingAccessToken" auto-complete="off"></el-input>
</el-form-item>
<el-form-item v-show="addForm.isDingDingNotify.toString()==='true'" label="提醒策略">
<el-checkbox
v-model="addForm.dingdingNotifyStrategy.success"
label="测试全通过时提醒">
</el-checkbox>
<el-checkbox
v-model="addForm.dingdingNotifyStrategy.fail"
label="测试存在失败时提醒">
</el-checkbox>
</el-form-item>
</div>
</transition>
<el-form-item label="企微提醒">
<el-radio
v-model="addForm.isEnterpriseWechatNotify"
:label="true">
</el-radio>
<el-radio
v-model="addForm.isEnterpriseWechatNotify"
:label="false">
</el-radio>
</el-form-item>
<transition name="el-zoom-in-top">
<div
class="form-item-sub form-item-short"
v-if="addForm.isEnterpriseWechatNotify && addForm.isEnterpriseWechatNotify.toString()==='true'">
<el-form-item
style="width:90%"
label="企微Token"
prop="enterpriseWechatAccessToken">
<el-input placeholder="如: 618311c0-yd0f-37e0-b11d-9f7c521d8gb9" v-model.trim="addForm.enterpriseWechatAccessToken" auto-complete="off"></el-input>
</el-form-item>
<el-form-item v-show="addForm.isEnterpriseWechatNotify.toString()==='true'" label="提醒策略">
<el-checkbox
v-model="addForm.enterpriseWechatNotifyStrategy.success"
label="测试全通过时提醒">
</el-checkbox>
<el-checkbox
v-model="addForm.enterpriseWechatNotifyStrategy.fail"
label="测试存在失败时提醒">
</el-checkbox>
</el-form-item>
</div>
</transition>
<el-form-item label="告警邮箱" prop="alarmMailList">
<el-select clearable style="width: 60%;" v-model="addForm['alarmMailList']" @visible-change="checkActiveMailList" multiple placeholder="请选择告警报告接受者(可多选)">
<el-option v-for="(item,index) in alarmMailList" :key="index" :label="item.name" :value="item.mailAddress"></el-option>
......@@ -276,6 +424,12 @@
alarmMailList: [
{ required: false, message: '请选择告警邮箱', trigger: 'blur' }
],
isDingDingNotify: [
{ required: false, message: '请选择是否使用钉钉提醒', trigger: 'blur' }
],
dingdingAccessToken: [
{ required: false, message: '请输入钉钉AccessToken', trigger: 'blur' }
],
triggerType: [
{ required: true, message: '请选择触发类型', trigger: 'blur' }
],
......@@ -298,6 +452,12 @@
isExecuteForbiddenedCase: false,
testDomain: '',
alarmMailList: [],
isDingDingNotify: false,
dingdingNotifyStrategy: {success: false, fail: true},
dingdingAccessToken: '',
isEnterpriseWechatNotify: false,
enterpriseWechatNotifyStrategy: {success: false, fail: true},
enterpriseWechatAccessToken: '',
triggerType: '',
interval: 0,
runDate: '',
......@@ -319,6 +479,12 @@
alarmMailList: [
{ required: false, message: '请选择告警邮箱', trigger: 'blur' }
],
isDingDingNotify: [
{ required: false, message: '请选择是否使用钉钉提醒', trigger: 'blur' }
],
dingdingAccessToken: [
{ required: false, message: '请输入钉钉AccessToken', trigger: 'blur' }
],
triggerType: [
{ required: true, message: '请选择触发类型', trigger: 'blur' }
],
......@@ -341,6 +507,12 @@
isExecuteForbiddenedCase: false,
testDomain: '',
alarmMailList: [],
isDingDingNotify: false,
dingdingNotifyStrategy: {success: false, fail: true},
dingdingAccessToken: '',
isEnterpriseWechatNotify: false,
enterpriseWechatNotifyStrategy: {success: false, fail: true},
enterpriseWechatAccessToken: '',
triggerType: '',
interval: '',
runDate: '',
......@@ -550,6 +722,12 @@
triggerType: self.addForm.triggerType,
description: self.addForm.description,
alarmMailList: self.addForm.alarmMailList,
isDingDingNotify: self.addForm.isDingDingNotify,
dingdingAccessToken: self.addForm.dingdingAccessToken,
dingdingNotifyStrategy: self.addForm.dingdingNotifyStrategy,
isEnterpriseWechatNotify: self.addForm.isEnterpriseWechatNotify,
enterpriseWechatAccessToken: self.addForm.enterpriseWechatAccessToken,
enterpriseWechatNotifyStrategy: self.addForm.enterpriseWechatNotifyStrategy,
creatorNickName: unescape(getCookie('nickName').replace(/\\u/g, '%u')) || '未知用户',
lastUpdatorNickName: unescape(getCookie('nickName').replace(/\\u/g, '%u')) || '未知用户'
};
......@@ -624,6 +802,12 @@
next_run_time: self.editForm.next_run_time, // 用于判断是否要resume定时任务
description: self.editForm.description,
alarmMailList: self.editForm.alarmMailList,
isDingDingNotify: self.editForm.isDingDingNotify || false,
dingdingAccessToken: self.editForm.dingdingAccessToken || '',
dingdingNotifyStrategy: self.editForm.dingdingNotifyStrategy,
isEnterpriseWechatNotify: self.editForm.isEnterpriseWechatNotify || false,
enterpriseWechatAccessToken: self.editForm.enterpriseWechatAccessToken || '',
enterpriseWechatNotifyStrategy: self.editForm.enterpriseWechatNotifyStrategy,
lastUpdatorNickName: unescape(getCookie('nickName').replace(/\\u/g, '%u')) || '未知用户'
};
if (self.editForm.runDate && self.editForm.runDate.toString().trim() !== ''){
......
images/泰斯特平台LOGO.png

124.3 KB | W: | H:

images/泰斯特平台LOGO.png

110.6 KB | W: | H:

images/泰斯特平台LOGO.png
images/泰斯特平台LOGO.png
images/泰斯特平台LOGO.png
images/泰斯特平台LOGO.png
  • 2-up
  • Swipe
  • Onion skin
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册