Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
a6289cd55d
|
@ -6,11 +6,11 @@ ARG MS_VERSION=dev
|
|||
|
||||
RUN mkdir -p /opt/apps && mkdir -p /opt/jmeter
|
||||
|
||||
COPY backend/target/backend-1.4.jar /opt/apps
|
||||
COPY backend/target/backend-1.5.jar /opt/apps
|
||||
|
||||
COPY backend/target/classes/jmeter/ /opt/jmeter/
|
||||
|
||||
ENV JAVA_APP_JAR=/opt/apps/backend-1.4.jar
|
||||
ENV JAVA_APP_JAR=/opt/apps/backend-1.5.jar
|
||||
|
||||
ENV AB_OFF=true
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ MeterSphere is a one-stop open-source enterprise-class continuous testing platfo
|
|||
Only need two steps to install MeterSphere:
|
||||
|
||||
What you need:
|
||||
1. Prepare a 64-bit Linux host with no less than 8 G RAM
|
||||
2. Log into root user and execute the command down below to install MeterSphere
|
||||
1. Prepare a 64-bit Linux host with no less than 8 G RAM
|
||||
2. Log into root user and execute the command down below to install MeterSphere
|
||||
|
||||
```sh
|
||||
curl -sSL https://github.com/metersphere/metersphere/releases/latest/download/quick_start.sh | sh
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<artifactId>metersphere-server</artifactId>
|
||||
<groupId>io.metersphere</groupId>
|
||||
<version>1.4</version>
|
||||
<version>1.5</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -44,7 +44,7 @@ public class ShiroConfig implements EnvironmentAware {
|
|||
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
||||
ShiroUtils.loadBaseFilterChain(filterChainDefinitionMap);
|
||||
filterChainDefinitionMap.put("/display/info", "anon");
|
||||
filterChainDefinitionMap.put("/display/file/*", "anon");
|
||||
filterChainDefinitionMap.put("/display/file/**", "anon");
|
||||
filterChainDefinitionMap.put("/**", "apikey, authc");
|
||||
return shiroFilterFactoryBean;
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ public class XmindCaseParser {
|
|||
JSONObject step = new JSONObject(true);
|
||||
step.put("num", i + 1);
|
||||
step.put("desc", attacheds.get(i).getTitle());
|
||||
if (attacheds.get(i) != null && attacheds.get(i).getChildren() != null && attacheds.get(i).getChildren().getAttached()!=null) {
|
||||
if (attacheds.get(i) != null && attacheds.get(i).getChildren() != null && attacheds.get(i).getChildren().getAttached() != null) {
|
||||
step.put("result", attacheds.get(i).getChildren().getAttached().get(0).getTitle());
|
||||
}
|
||||
jsonArray.add(step);
|
||||
|
@ -283,17 +283,20 @@ public class XmindCaseParser {
|
|||
|
||||
// 测试步骤处理
|
||||
List<Attached> steps = new LinkedList<>();
|
||||
StringBuilder rc = new StringBuilder();
|
||||
if (attacheds != null && !attacheds.isEmpty()) {
|
||||
attacheds.forEach(item -> {
|
||||
if (isAvailable(item.getTitle(), PC_REGEX)) {
|
||||
testCase.setPrerequisite(replace(item.getTitle(), PC_REGEX));
|
||||
} else if (isAvailable(item.getTitle(), RC_REGEX)) {
|
||||
testCase.setRemark(replace(item.getTitle(), RC_REGEX));
|
||||
rc.append(replace(item.getTitle(), RC_REGEX));
|
||||
rc.append("\n");
|
||||
} else {
|
||||
steps.add(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
testCase.setRemark(rc.toString());
|
||||
testCase.setSteps(this.getSteps(steps));
|
||||
testCases.add(testCase);
|
||||
// 校验合规性
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 57d6f78efa4b0300be188e8b024511ceef0873ed
|
||||
Subproject commit bb494fc68a2367359c9048fa7250c7618de4afb6
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<artifactId>metersphere-server</artifactId>
|
||||
<groupId>io.metersphere</groupId>
|
||||
<version>1.4</version>
|
||||
<version>1.5</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
</el-row>
|
||||
<el-row id="header-top" type="flex" justify="space-between" align="middle">
|
||||
<el-col :span="12">
|
||||
<img v-if="logoId" :src="'/display/file/' + logoId" style="width: 156px;height: 37px;" alt="">
|
||||
<a v-else class="logo"/>
|
||||
<img :src="'/display/file/logo'" style="width: 156px;height: 37px;" alt="">
|
||||
<ms-top-menus/>
|
||||
</el-col>
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ export class Test extends BaseConfig {
|
|||
constructor(options) {
|
||||
super();
|
||||
this.type = "MS API CONFIG";
|
||||
this.version = '1.4.0';
|
||||
this.version = '1.5.0';
|
||||
this.id = uuid();
|
||||
this.name = undefined;
|
||||
this.projectId = undefined;
|
||||
|
|
|
@ -204,6 +204,7 @@ export default {
|
|||
});
|
||||
}
|
||||
},
|
||||
|
||||
submit(formName) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
|
@ -282,7 +283,18 @@ export default {
|
|||
},
|
||||
openEnvironmentConfig(project) {
|
||||
this.$refs.environmentConfig.open(project.id);
|
||||
}
|
||||
},
|
||||
handleEvent(event) {
|
||||
if (event.keyCode === 13) {
|
||||
this.submit('form')
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
document.addEventListener('keydown', this.handleEvent)
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener('keydown', this.handleEvent);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {getCurrentUser, listenGoBack, removeGoBackListener} from "../../../../common/js/utils";
|
||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
import {PHONE_REGEX} from "@/common/js/regex";
|
||||
|
||||
export default {
|
||||
name: "MsPersonSetting",
|
||||
|
@ -115,7 +116,7 @@
|
|||
phone: [
|
||||
{
|
||||
required: false,
|
||||
pattern: '^1(3|4|5|7|8)\\d{9}$',
|
||||
pattern: PHONE_REGEX,
|
||||
message: this.$t('member.mobile_number_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
|
|
|
@ -338,6 +338,7 @@ import {hasRole, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
|||
import MsRolesTag from "../../common/components/MsRolesTag";
|
||||
import {ROLE_ADMIN} from "@/common/js/constants";
|
||||
import {getCurrentUser} from "../../../../common/js/utils";
|
||||
import {PHONE_REGEX} from "@/common/js/regex";
|
||||
|
||||
export default {
|
||||
name: "MsUser",
|
||||
|
@ -380,7 +381,7 @@ export default {
|
|||
rule: {
|
||||
id: [
|
||||
{required: true, message: this.$t('user.input_id'), trigger: 'blur'},
|
||||
{min: 2, max: 50, message: this.$t('commons.input_limit', [2, 50]), trigger: 'blur'},
|
||||
{min: 1, max: 50, message: this.$t('commons.input_limit', [1, 50]), trigger: 'blur'},
|
||||
{
|
||||
required: true,
|
||||
pattern: '^[^\u4e00-\u9fa5]+$',
|
||||
|
@ -401,7 +402,7 @@ export default {
|
|||
{required: true, message: this.$t('user.input_phone'), trigger: 'blur'},
|
||||
{
|
||||
required: true,
|
||||
pattern: '^1(3|4|5|7|8)\\d{9}$',
|
||||
pattern: PHONE_REGEX,
|
||||
message: this.$t('user.mobile_number_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
|
|
|
@ -215,6 +215,16 @@
|
|||
item.checked = false;
|
||||
});
|
||||
flag ? this.testCases = tableData : this.testCases = this.testCases.concat(tableData);
|
||||
// 去重处理
|
||||
let hash = {}
|
||||
this.testCases = this.testCases.reduce((item, next) => {
|
||||
if (!hash[next.id]) {
|
||||
hash[next.id] = true
|
||||
item.push(next)
|
||||
}
|
||||
return item
|
||||
}, [])
|
||||
|
||||
this.lineStatus = tableData.length === 50 && this.testCases.length < this.total;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
this.listenGoBack();
|
||||
},
|
||||
initComponents() {
|
||||
this.componentMap.forEach((value, key) =>{
|
||||
this.componentMap.forEach((value, key) => {
|
||||
if (this.template.content.components.indexOf(key) < 0 && this.components.indexOf(key) < 0) {
|
||||
this.components.push(key);
|
||||
}
|
||||
|
@ -205,7 +205,7 @@
|
|||
if (this.isReport) {
|
||||
url = '/case/report/get/';
|
||||
}
|
||||
this.$get(url + id, (response) =>{
|
||||
this.$get(url + id, (response) => {
|
||||
this.template = response.data;
|
||||
this.template.content = JSON.parse(response.data.content);
|
||||
if (this.template.content.customComponent) {
|
||||
|
@ -238,7 +238,7 @@
|
|||
if (this.isReport) {
|
||||
url = '/case/report/';
|
||||
}
|
||||
this.$post(url + this.type, param, () =>{
|
||||
this.$post(url + this.type, param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.handleClose();
|
||||
this.$emit('refresh');
|
||||
|
|
|
@ -23,9 +23,10 @@
|
|||
resize="none"
|
||||
:autosize="{ minRows: 4, maxRows: 4}"
|
||||
@keyup.ctrl.enter.native="sendComment"
|
||||
:disabled="isReadOnly"
|
||||
>
|
||||
</el-input>
|
||||
<el-button type="primary" size="mini" class="send-btn" @click="sendComment">
|
||||
<el-button type="primary" size="mini" class="send-btn" @click="sendComment" :disabled="isReadOnly">
|
||||
{{ $t('test_track.comment.send') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
@ -34,6 +35,7 @@
|
|||
|
||||
<script>
|
||||
import ReviewCommentItem from "./ReviewCommentItem";
|
||||
import {checkoutTestManagerOrTestUser} from "@/common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "ReviewComment",
|
||||
|
@ -47,8 +49,12 @@ export default {
|
|||
return {
|
||||
result: {},
|
||||
textarea: '',
|
||||
isReadOnly: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.isReadOnly = !checkoutTestManagerOrTestUser();
|
||||
},
|
||||
methods: {
|
||||
sendComment() {
|
||||
let comment = {};
|
||||
|
|
|
@ -219,6 +219,15 @@
|
|||
item.checked = false;
|
||||
});
|
||||
flag ? this.testReviews = tableData : this.testReviews = this.testReviews.concat(tableData);
|
||||
// 去重处理
|
||||
let hash = {}
|
||||
this.testReviews = this.testReviews.reduce((item, next) => {
|
||||
if (!hash[next.id]) {
|
||||
hash[next.id] = true
|
||||
item.push(next)
|
||||
}
|
||||
return item
|
||||
}, [])
|
||||
this.lineStatus = tableData.length === 50 && this.testReviews.length < this.total;
|
||||
|
||||
});
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 71d57ae5d7f8bb5c93a29504ac6f2300dc189ce9
|
||||
Subproject commit 8a972a198775b3783ed6e4cef27197e53d1ebdc8
|
|
@ -110,9 +110,7 @@ body {
|
|||
}
|
||||
|
||||
/* 修复带长度限制的文本框,内容太长造成的无法查看内容的问题 */
|
||||
/*.el-input-padding-fix .el-input__inner {*/
|
||||
/*padding-right: 60px ;*/
|
||||
/*}*/
|
||||
|
||||
.el-input__inner[maxlength] {
|
||||
padding-right: 60px ;
|
||||
padding-right: 60px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export const PHONE_REGEX = '^1(3|4|5|7|8|9)\\d{9}$';
|
|
@ -4,8 +4,7 @@
|
|||
<el-col :span="12">
|
||||
<el-form :model="form" :rules="rules" ref="form">
|
||||
<div class="logo">
|
||||
<img v-if="loginLogoId" :src="'/display/file/' + loginLogoId" style="width: 224px;height: 45px;" alt="">
|
||||
<img v-else src="../assets/logo-dark-MeterSphere.svg" style="width: 224px; " alt="">
|
||||
<img :src="'/display/file/loginLogo'" style="width: 224px;height: 45px;" alt="">
|
||||
</div>
|
||||
<div class="title">
|
||||
<span id="s1">{{ loginTitle }}</span>
|
||||
|
@ -41,8 +40,7 @@
|
|||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<img v-if="loginImageId" :src="'/display/file/' + loginImageId" style="height: 560px; width: 100%">
|
||||
<img v-else src="../assets/info.png" style="height: 560px; width: 100%">
|
||||
<img :src="'/display/file/loginImage'" style="height: 560px; width: 100%">
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
@ -86,8 +84,6 @@ export default {
|
|||
msg: '',
|
||||
ready: false,
|
||||
openLdap: false,
|
||||
loginLogoId: '_blank',
|
||||
loginImageId: '_blank',
|
||||
loginTitle: this.$t("commons.login") + " MeterSphere"
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue