yapi-plugin-auto-test
Version:
YAPI自动化测试插件,支持在YAPI设置测试计划,查看历史测试结果,自定义通知。
301 lines (279 loc) • 10 kB
JavaScript
import React, { Component } from "react";
import PropTypes from "prop-types";
import { formatTime } from "client/common.js";
import { Form, Switch, Button, Input, Icon, Tooltip, Checkbox, InputNumber } from "antd";
const FormItem = Form.Item;
import "./index.scss"
// layout
const formItemLayout = {
labelCol: {
lg: { span: 5 },
xs: { span: 24 },
sm: { span: 10 }
},
wrapperCol: {
lg: { span: 16 },
xs: { span: 24 },
sm: { span: 12 }
},
className: "form-item"
};
const tailFormItemLayout = {
wrapperCol: {
sm: {
span: 16,
offset: 11
}
}
};
const triggerOptions = [
{ label: "执行结束", value: "any" },
{ label: "不发送", value: "never" },
{ label: "全部通过", value: "success" },
{ label: "全部失败", value: "fail" },
{ label: "部分失败", value: "part" }
];
.create()
export default class Add extends Component {
static propTypes = {
form: PropTypes.object,
planMsg: PropTypes.object,
onSubmit: PropTypes.func,
handleNameInput: PropTypes.func,
planNames: PropTypes.array
};
constructor(props) {
super(props);
this.state = {
auto_test_data: props.planMsg,
notifier_url: props.planMsg.notifier && props.planMsg.notifier.url
};
}
// 获取兼容后的触发器
getCompatibleTrigger = plan => {
if (!plan.notice_triggers && plan.notice_trigger) {
return [plan.notice_trigger];
}
return plan.notice_triggers || ["never"];
}
handleSubmit = async () => {
const { form, planMsg, onSubmit } = this.props;
let params = {
id: planMsg._id,
project_id: planMsg.project_id,
is_plan_open: this.state.auto_test_data.is_plan_open,
notifier_url: this.state.notifier_url
};
form.validateFields(async (err, values) => {
if (!err) {
let assignValue = Object.assign(params, values);
onSubmit(assignValue);
}
});
};
componentWillMount() {
//默认每小时随机数分钟同步一次
this.setState({
random_corn: "1 " + Math.round(Math.random() * 60) + " * * * *"
});
}
// 是否开启
onChange = v => {
let auto_test_data = this.state.auto_test_data;
auto_test_data.is_plan_open = v;
this.setState({
auto_test_data: auto_test_data
});
}
onTriggerChange = v => {
let auto_test_data = this.state.auto_test_data;
auto_test_data.notice_triggers = v;
this.setState({
auto_test_data: auto_test_data
});
}
// 打开一个新窗口执行一次计划
runPlan = () => {
const { form } = this.props;
form.validateFields(async (err, values) => {
if (!err) {
window.open(values.plan_url, "_blank");
}
});
}
render() {
const { planNames, planMsg } = this.props;
const { getFieldDecorator } = this.props.form;
return (
<div className="m-panel">
<Form>
<FormItem
label="是否执行测试计划"
{...formItemLayout}
>
<Switch
checked={this.state.auto_test_data.is_plan_open}
onChange={this.onChange}
checkedChildren="开"
unCheckedChildren="关"
/>
{planMsg._id ? (<Button
type="primary"
icon="play-circle"
className="run-once"
onClick={this.runPlan}
>
执行一次
</Button>) : null}
{this.state.auto_test_data.last_test_time != null ?
(<div>上次执行时间: <span className="testtime">{formatTime(this.state.auto_test_data.last_test_time)}</span></div>) : null}
</FormItem>
<div>
<FormItem {...formItemLayout} label="计划名称">
{getFieldDecorator("plan_name", {
rules: [
{
required: true,
message: "请输入计划名称"
},
{
validator: (rule, value, callback) => {
if (value) {
if (planNames.includes(value)) {
callback("计划名称重复");
} else if (!/\S/.test(value)) {
callback("请输入计划名称");
} else {
callback();
}
} else {
callback("请输入计划名称");
}
}
}
],
validateTrigger: "onBlur",
initialValue: this.state.auto_test_data._id === 0 ? "" : this.state.auto_test_data.plan_name
})(<Input onChange={e => this.props.handleNameInput(e.target.value)} />)}
</FormItem>
<FormItem {...formItemLayout}
label={
<span>
自动测试URL
<Tooltip title="复制测试集合服务端测试的URL">
<Icon type="question-circle-o" />
</Tooltip>
</span>
}>
{getFieldDecorator("plan_url", {
rules: [
{
required: true,
message: "请输入服务器端自动测试URL"
}
],
validateTrigger: "onBlur",
initialValue: this.state.auto_test_data.plan_url
})(<Input />)}
</FormItem>
<FormItem {...formItemLayout} label={<span>类cron风格表达式 <a href="https://github.com/node-schedule/node-schedule">GitHub</a></span>}>
{getFieldDecorator("plan_cron", {
rules: [
{
required: true,
message: "请输入node-schedule的类cron表达式!"
}
],
initialValue: this.state.auto_test_data.plan_cron ? this.state.auto_test_data.plan_cron : this.state.random_corn
})(<Input />)}
</FormItem>
<FormItem {...formItemLayout} label={
<span>
保留测试结果数,-1为不限
<Tooltip title="配置影响每个测试计划保留的测试结果数,设置为-1表示不限,下次执行生效">
<Icon type="question-circle-o" />
</Tooltip>
</span>
}>
{getFieldDecorator("plan_result_size", {
rules: [
{
required: true,
message: "请输入保留次数"
}, {
validator: (rule, value, callback) => {
if (value !== "") {
if (!/^\d+$/.test(value) && value != -1) {
callback("请输入非负整数或-1");
} else {
callback();
}
} else {
callback("请输入保留次数");
}
}
}
],
validateTrigger: "onBlur",
initialValue: this.state.auto_test_data.plan_result_size
})(<InputNumber min={-1} />)}
</FormItem>
<FormItem {...formItemLayout} label={
<span>
失败后重复执行次数
<Tooltip title="当执行完成之后如果存在失败的情况会自动重新执行">
<Icon type="question-circle-o" />
</Tooltip>
</span>
}>
{getFieldDecorator("plan_fail_retries", {
rules: [
{
required: true,
message: "请输入次数"
}, {
validator: (rule, value, callback) => {
if (value !== "") {
if (!/^\d+$/.test(value)) {
callback("请输入非负整数");
} else if (parseInt(value, 10) > 10) {
callback("考虑服务器压力,单个任务暂不支持10次以上重试");
} else {
callback();
}
} else {
callback("请输入次数");
}
}
}
],
validateTrigger: "onBlur",
initialValue: this.state.auto_test_data.plan_fail_retries
})(<InputNumber min={0} />)}
</FormItem>
<FormItem {...formItemLayout} label="触发通知">
{getFieldDecorator("notice_triggers", {
initialValue: this.getCompatibleTrigger(this.state.auto_test_data)
})(
<Checkbox.Group
options={triggerOptions}
onChange={this.onTriggerChange}
/>
)}
</FormItem>
<FormItem {...formItemLayout} label={<span>通知机器人URL <a rel="noopener noreferrer" target="_blank" href="https://github.com/congqiu/yapi-plugin-auto-test/blob/master/README.md#%E6%B5%8B%E8%AF%95%E8%AE%A1%E5%88%92">文档</a></span>}>
{getFieldDecorator("notifier_url", {
initialValue: this.state.notifier_url
})(<Input placeholder="企业微信、钉钉机器人完整地址或自定义webhook的地址" />)}
</FormItem>
</div>
<FormItem {...tailFormItemLayout}>
<Button type="primary" htmlType="submit" icon="save" size="large" onClick={this.handleSubmit}>
保存
</Button>
</FormItem>
</Form>
</div>
);
}
}