Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
0bd3d0355b
|
@ -13,4 +13,9 @@ public class ApiScenarioDTO extends ApiScenarioWithBLOBs {
|
|||
private String projectName;
|
||||
private String userName;
|
||||
private List<String> tagNames;
|
||||
|
||||
/**
|
||||
* 场景跨项目ID
|
||||
*/
|
||||
private List<String> projectIds;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import io.metersphere.api.service.ApiTestEnvironmentService;
|
|||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.ScriptEngineUtils;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
@ -132,7 +133,7 @@ public class MsScenario extends MsTestElement {
|
|||
// 场景变量和环境变量
|
||||
Arguments arguments = arguments(config);
|
||||
if (arguments != null) {
|
||||
tree.add(arguments);
|
||||
tree.add(config.valueSupposeMock(arguments));
|
||||
}
|
||||
this.addCsvDataSet(tree, variables);
|
||||
this.addCounter(tree, variables);
|
||||
|
|
|
@ -2,7 +2,9 @@ package io.metersphere.api.dto.definition.request;
|
|||
|
||||
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
|
||||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||
import io.metersphere.commons.utils.ScriptEngineUtils;
|
||||
import lombok.Data;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -37,4 +39,13 @@ public class ParameterConfig {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public Arguments valueSupposeMock(Arguments arguments) {
|
||||
for(int i = 0; i < arguments.getArguments().size(); ++i) {
|
||||
String argValue = arguments.getArgument(i).getValue();
|
||||
arguments.getArgument(i).setValue(ScriptEngineUtils.calculate(argValue));
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
}
|
|
@ -122,7 +122,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
// 添加环境中的公共变量
|
||||
Arguments arguments = this.addArguments(config);
|
||||
if (arguments != null) {
|
||||
tree.add(arguments);
|
||||
tree.add(config.valueSupposeMock(arguments));
|
||||
}
|
||||
try {
|
||||
if (config.isEffective(this.getProjectId())) {
|
||||
|
|
|
@ -654,24 +654,29 @@ public class ApiAutomationService {
|
|||
}
|
||||
|
||||
public void relevance(ApiCaseRelevanceRequest request) {
|
||||
List<String> ids = request.getSelectIds();
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
Map<String, List<String>> mapping = request.getMapping();
|
||||
Map<String, String> envMap = request.getEnvMap();
|
||||
Set<String> set = mapping.keySet();
|
||||
if (set.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<ApiScenario> apiScenarios = selectByIds(ids);
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
|
||||
ExtTestPlanScenarioCaseMapper batchMapper = sqlSession.getMapper(ExtTestPlanScenarioCaseMapper.class);
|
||||
apiScenarios.forEach(scenario -> {
|
||||
set.forEach(id -> {
|
||||
Map<String, String> newEnvMap = new HashMap<>(16);
|
||||
if (envMap != null && !envMap.isEmpty()) {
|
||||
List<String> list = mapping.get(id);
|
||||
list.forEach(l -> {
|
||||
newEnvMap.put(l, envMap.get(l));
|
||||
});
|
||||
}
|
||||
TestPlanApiScenario testPlanApiScenario = new TestPlanApiScenario();
|
||||
testPlanApiScenario.setId(UUID.randomUUID().toString());
|
||||
testPlanApiScenario.setApiScenarioId(scenario.getId());
|
||||
testPlanApiScenario.setApiScenarioId(id);
|
||||
testPlanApiScenario.setTestPlanId(request.getPlanId());
|
||||
testPlanApiScenario.setCreateTime(System.currentTimeMillis());
|
||||
testPlanApiScenario.setUpdateTime(System.currentTimeMillis());
|
||||
batchMapper.insertIfNotExists(testPlanApiScenario);
|
||||
testPlanApiScenario.setEnvironment(JSON.toJSONString(newEnvMap));
|
||||
testPlanApiScenarioMapper.insert(testPlanApiScenario);
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
||||
public List<ApiScenario> selectByIds(List<String> ids) {
|
||||
|
|
|
@ -22,6 +22,7 @@ import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
|
|||
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper;
|
||||
import io.metersphere.commons.constants.TestPlanStatus;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.i18n.Translator;
|
||||
|
@ -49,6 +50,8 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ApiTestCaseService {
|
||||
@Resource
|
||||
TestPlanMapper testPlanMapper;
|
||||
@Resource
|
||||
private ApiTestCaseMapper apiTestCaseMapper;
|
||||
@Resource
|
||||
|
@ -330,6 +333,14 @@ public class ApiTestCaseService {
|
|||
testPlanApiCase.setUpdateTime(System.currentTimeMillis());
|
||||
batchMapper.insertIfNotExists(testPlanApiCase);
|
||||
});
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getPlanId());
|
||||
if (StringUtils.equals(testPlan.getStatus(), TestPlanStatus.Prepare.name())
|
||||
|| StringUtils.equals(testPlan.getStatus(), TestPlanStatus.Completed.name())) {
|
||||
testPlan.setStatus(TestPlanStatus.Underway.name());
|
||||
testPlan.setActualStartTime(System.currentTimeMillis()); // 将状态更新为进行中时,开始时间也要更新
|
||||
testPlan.setActualEndTime(null);
|
||||
testPlanMapper.updateByPrimaryKey(testPlan);
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@ public class TestPlanApiScenario implements Serializable {
|
|||
|
||||
private String status;
|
||||
|
||||
private String environmentId;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
private Long updateTime;
|
||||
|
@ -25,5 +23,7 @@ public class TestPlanApiScenario implements Serializable {
|
|||
|
||||
private String reportId;
|
||||
|
||||
private String environment;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -384,76 +384,6 @@ public class TestPlanApiScenarioExample {
|
|||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdIsNull() {
|
||||
addCriterion("environment_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdIsNotNull() {
|
||||
addCriterion("environment_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdEqualTo(String value) {
|
||||
addCriterion("environment_id =", value, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdNotEqualTo(String value) {
|
||||
addCriterion("environment_id <>", value, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdGreaterThan(String value) {
|
||||
addCriterion("environment_id >", value, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("environment_id >=", value, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdLessThan(String value) {
|
||||
addCriterion("environment_id <", value, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdLessThanOrEqualTo(String value) {
|
||||
addCriterion("environment_id <=", value, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdLike(String value) {
|
||||
addCriterion("environment_id like", value, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdNotLike(String value) {
|
||||
addCriterion("environment_id not like", value, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdIn(List<String> values) {
|
||||
addCriterion("environment_id in", values, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdNotIn(List<String> values) {
|
||||
addCriterion("environment_id not in", values, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdBetween(String value1, String value2) {
|
||||
addCriterion("environment_id between", value1, value2, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnvironmentIdNotBetween(String value1, String value2) {
|
||||
addCriterion("environment_id not between", value1, value2, "environmentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeIsNull() {
|
||||
addCriterion("create_time is null");
|
||||
return (Criteria) this;
|
||||
|
|
|
@ -16,15 +16,21 @@ public interface TestPlanApiScenarioMapper {
|
|||
|
||||
int insertSelective(TestPlanApiScenario record);
|
||||
|
||||
List<TestPlanApiScenario> selectByExampleWithBLOBs(TestPlanApiScenarioExample example);
|
||||
|
||||
List<TestPlanApiScenario> selectByExample(TestPlanApiScenarioExample example);
|
||||
|
||||
TestPlanApiScenario selectByPrimaryKey(String id);
|
||||
|
||||
int updateByExampleSelective(@Param("record") TestPlanApiScenario record, @Param("example") TestPlanApiScenarioExample example);
|
||||
|
||||
int updateByExampleWithBLOBs(@Param("record") TestPlanApiScenario record, @Param("example") TestPlanApiScenarioExample example);
|
||||
|
||||
int updateByExample(@Param("record") TestPlanApiScenario record, @Param("example") TestPlanApiScenarioExample example);
|
||||
|
||||
int updateByPrimaryKeySelective(TestPlanApiScenario record);
|
||||
|
||||
int updateByPrimaryKeyWithBLOBs(TestPlanApiScenario record);
|
||||
|
||||
int updateByPrimaryKey(TestPlanApiScenario record);
|
||||
}
|
|
@ -6,13 +6,15 @@
|
|||
<result column="test_plan_id" jdbcType="VARCHAR" property="testPlanId" />
|
||||
<result column="api_scenario_id" jdbcType="VARCHAR" property="apiScenarioId" />
|
||||
<result column="status" jdbcType="VARCHAR" property="status" />
|
||||
<result column="environment_id" jdbcType="VARCHAR" property="environmentId" />
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||
<result column="pass_rate" jdbcType="VARCHAR" property="passRate" />
|
||||
<result column="last_result" jdbcType="VARCHAR" property="lastResult" />
|
||||
<result column="report_id" jdbcType="VARCHAR" property="reportId" />
|
||||
</resultMap>
|
||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.TestPlanApiScenario">
|
||||
<result column="environment" jdbcType="LONGVARCHAR" property="environment" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="oredCriteria" item="criteria" separator="or">
|
||||
|
@ -72,9 +74,28 @@
|
|||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, test_plan_id, api_scenario_id, `status`, environment_id, create_time, update_time,
|
||||
pass_rate, last_result, report_id
|
||||
id, test_plan_id, api_scenario_id, `status`, create_time, update_time, pass_rate,
|
||||
last_result, report_id
|
||||
</sql>
|
||||
<sql id="Blob_Column_List">
|
||||
environment
|
||||
</sql>
|
||||
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.TestPlanApiScenarioExample" resultMap="ResultMapWithBLOBs">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
,
|
||||
<include refid="Blob_Column_List" />
|
||||
from test_plan_api_scenario
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestPlanApiScenarioExample" resultMap="BaseResultMap">
|
||||
select
|
||||
<if test="distinct">
|
||||
|
@ -89,9 +110,11 @@
|
|||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
,
|
||||
<include refid="Blob_Column_List" />
|
||||
from test_plan_api_scenario
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</select>
|
||||
|
@ -107,13 +130,13 @@
|
|||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.TestPlanApiScenario">
|
||||
insert into test_plan_api_scenario (id, test_plan_id, api_scenario_id,
|
||||
`status`, environment_id, create_time,
|
||||
update_time, pass_rate, last_result,
|
||||
report_id)
|
||||
`status`, create_time, update_time,
|
||||
pass_rate, last_result, report_id,
|
||||
environment)
|
||||
values (#{id,jdbcType=VARCHAR}, #{testPlanId,jdbcType=VARCHAR}, #{apiScenarioId,jdbcType=VARCHAR},
|
||||
#{status,jdbcType=VARCHAR}, #{environmentId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT},
|
||||
#{updateTime,jdbcType=BIGINT}, #{passRate,jdbcType=VARCHAR}, #{lastResult,jdbcType=VARCHAR},
|
||||
#{reportId,jdbcType=VARCHAR})
|
||||
#{status,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||
#{passRate,jdbcType=VARCHAR}, #{lastResult,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
|
||||
#{environment,jdbcType=LONGVARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlanApiScenario">
|
||||
insert into test_plan_api_scenario
|
||||
|
@ -130,9 +153,6 @@
|
|||
<if test="status != null">
|
||||
`status`,
|
||||
</if>
|
||||
<if test="environmentId != null">
|
||||
environment_id,
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time,
|
||||
</if>
|
||||
|
@ -148,6 +168,9 @@
|
|||
<if test="reportId != null">
|
||||
report_id,
|
||||
</if>
|
||||
<if test="environment != null">
|
||||
environment,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
|
@ -162,9 +185,6 @@
|
|||
<if test="status != null">
|
||||
#{status,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="environmentId != null">
|
||||
#{environmentId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
#{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
|
@ -180,6 +200,9 @@
|
|||
<if test="reportId != null">
|
||||
#{reportId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="environment != null">
|
||||
#{environment,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.TestPlanApiScenarioExample" resultType="java.lang.Long">
|
||||
|
@ -203,9 +226,6 @@
|
|||
<if test="record.status != null">
|
||||
`status` = #{record.status,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.environmentId != null">
|
||||
environment_id = #{record.environmentId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.createTime != null">
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
|
@ -221,18 +241,36 @@
|
|||
<if test="record.reportId != null">
|
||||
report_id = #{record.reportId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.environment != null">
|
||||
environment = #{record.environment,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExampleWithBLOBs" parameterType="map">
|
||||
update test_plan_api_scenario
|
||||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
|
||||
api_scenario_id = #{record.apiScenarioId,jdbcType=VARCHAR},
|
||||
`status` = #{record.status,jdbcType=VARCHAR},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
pass_rate = #{record.passRate,jdbcType=VARCHAR},
|
||||
last_result = #{record.lastResult,jdbcType=VARCHAR},
|
||||
report_id = #{record.reportId,jdbcType=VARCHAR},
|
||||
environment = #{record.environment,jdbcType=LONGVARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update test_plan_api_scenario
|
||||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
|
||||
api_scenario_id = #{record.apiScenarioId,jdbcType=VARCHAR},
|
||||
`status` = #{record.status,jdbcType=VARCHAR},
|
||||
environment_id = #{record.environmentId,jdbcType=VARCHAR},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
pass_rate = #{record.passRate,jdbcType=VARCHAR},
|
||||
|
@ -254,9 +292,6 @@
|
|||
<if test="status != null">
|
||||
`status` = #{status,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="environmentId != null">
|
||||
environment_id = #{environmentId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
|
@ -272,15 +307,30 @@
|
|||
<if test="reportId != null">
|
||||
report_id = #{reportId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="environment != null">
|
||||
environment = #{environment,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.TestPlanApiScenario">
|
||||
update test_plan_api_scenario
|
||||
set test_plan_id = #{testPlanId,jdbcType=VARCHAR},
|
||||
api_scenario_id = #{apiScenarioId,jdbcType=VARCHAR},
|
||||
`status` = #{status,jdbcType=VARCHAR},
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
pass_rate = #{passRate,jdbcType=VARCHAR},
|
||||
last_result = #{lastResult,jdbcType=VARCHAR},
|
||||
report_id = #{reportId,jdbcType=VARCHAR},
|
||||
environment = #{environment,jdbcType=LONGVARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.TestPlanApiScenario">
|
||||
update test_plan_api_scenario
|
||||
set test_plan_id = #{testPlanId,jdbcType=VARCHAR},
|
||||
api_scenario_id = #{apiScenarioId,jdbcType=VARCHAR},
|
||||
`status` = #{status,jdbcType=VARCHAR},
|
||||
environment_id = #{environmentId,jdbcType=VARCHAR},
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
pass_rate = #{passRate,jdbcType=VARCHAR},
|
||||
|
|
|
@ -134,6 +134,7 @@
|
|||
</sql>
|
||||
<select id="list" resultMap="BaseResultMap">
|
||||
select api_scenario.id, api_scenario.project_id, api_scenario.tags, api_scenario.user_id, api_scenario.num,
|
||||
api_scenario.scenario_definition,
|
||||
api_scenario.api_scenario_module_id,api_scenario.module_path, api_scenario.name, api_scenario.level,
|
||||
api_scenario.status, api_scenario.principal, api_scenario.step_total, api_scenario.follow_people,
|
||||
api_scenario.last_result,api_scenario.pass_rate,api_scenario.report_id,
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<select id="list" resultType="io.metersphere.api.dto.automation.ApiScenarioDTO">
|
||||
select
|
||||
t.id, t.environment_id, t.create_time, t.update_time, t.last_result, t.pass_rate, t.report_id,
|
||||
t.id, t.environment, t.create_time, t.update_time, t.last_result, t.pass_rate, t.report_id, c.scenario_definition,
|
||||
c.id as case_id, c.project_id, c.user_id,c.api_scenario_module_id, c.module_path, c.name, c.level,
|
||||
c.status, c.principal, c.step_total, c.follow_people, c.schedule, c.description, c.tags, c.num,
|
||||
p.name as project_name, p.id as project_id, u.name as user_name
|
||||
|
|
|
@ -19,6 +19,8 @@ public class TestCaseExcelData {
|
|||
@ExcelIgnore
|
||||
private String priority;
|
||||
@ExcelIgnore
|
||||
private String tags;
|
||||
@ExcelIgnore
|
||||
private String method;
|
||||
@ExcelIgnore
|
||||
private String prerequisite;
|
||||
|
|
|
@ -38,6 +38,11 @@ public class TestCaseExcelDataCn extends TestCaseExcelData {
|
|||
@Pattern(regexp = "(^P0$)|(^P1$)|(^P2$)|(^P3$)", message = "{test_case_priority_validate}")
|
||||
private String priority;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("标签")
|
||||
@Length(min = 0, max = 1000)
|
||||
private String tags;
|
||||
|
||||
@NotBlank(message = "{cannot_be_null}")
|
||||
@ExcelProperty("测试方式")
|
||||
@Pattern(regexp = "(^manual$)|(^auto$)", message = "{test_case_method_validate}")
|
||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.commons.constants.RoleConstants;
|
|||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.track.dto.RelevanceScenarioRequest;
|
||||
import io.metersphere.track.request.testcase.TestPlanApiCaseBatchRequest;
|
||||
import io.metersphere.track.service.TestPlanScenarioCaseService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
|
@ -53,4 +54,10 @@ public class TestPlanScenarioCaseController {
|
|||
request.setExecuteType(ExecuteType.Completed.name());
|
||||
return testPlanScenarioCaseService.run(request);
|
||||
}
|
||||
|
||||
@PostMapping("/batch/update/env")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public void batchUpdateEnv(@RequestBody RelevanceScenarioRequest request) {
|
||||
testPlanScenarioCaseService.batchUpdateEnv(request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package io.metersphere.track.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class RelevanceScenarioRequest {
|
||||
|
||||
/**
|
||||
* 环境和项目对应关系
|
||||
*/
|
||||
private Map<String, String> envMap;
|
||||
|
||||
/**
|
||||
* 场景用例跨项目的关系
|
||||
*/
|
||||
private Map<String, List<String>> mapping;
|
||||
|
||||
}
|
|
@ -5,6 +5,7 @@ import lombok.Setter;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
@ -25,4 +26,14 @@ public class ApiCaseRelevanceRequest {
|
|||
* 具体要关联的用例
|
||||
*/
|
||||
private List<String> selectIds = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 项目环境对应关系
|
||||
*/
|
||||
private Map<String, String> envMap;
|
||||
|
||||
/**
|
||||
* 用例的环境的对应关系
|
||||
*/
|
||||
private Map<String, List<String>> mapping;
|
||||
}
|
||||
|
|
|
@ -483,6 +483,7 @@ public class TestCaseService {
|
|||
data.setType(t.getType());
|
||||
data.setMethod(t.getMethod());
|
||||
data.setPrerequisite(t.getPrerequisite());
|
||||
data.setTags(t.getTags());
|
||||
if (t.getMethod().equals("manual")) {
|
||||
String steps = t.getSteps();
|
||||
String setp = "";
|
||||
|
|
|
@ -4,7 +4,9 @@ import io.metersphere.base.domain.*;
|
|||
import io.metersphere.base.mapper.LoadTestMapper;
|
||||
import io.metersphere.base.mapper.LoadTestReportMapper;
|
||||
import io.metersphere.base.mapper.TestPlanLoadCaseMapper;
|
||||
import io.metersphere.base.mapper.TestPlanMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanLoadCaseMapper;
|
||||
import io.metersphere.commons.constants.TestPlanStatus;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
import io.metersphere.performance.request.RunTestPlanRequest;
|
||||
import io.metersphere.performance.service.PerformanceTestService;
|
||||
|
@ -28,7 +30,8 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanLoadCaseService {
|
||||
|
||||
@Resource
|
||||
TestPlanMapper testPlanMapper;
|
||||
@Resource
|
||||
private TestPlanLoadCaseMapper testPlanLoadCaseMapper;
|
||||
@Resource
|
||||
|
@ -78,6 +81,14 @@ public class TestPlanLoadCaseService {
|
|||
t.setUpdateTime(System.currentTimeMillis());
|
||||
testPlanLoadCaseMapper.insert(t);
|
||||
});
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getTestPlanId());
|
||||
if (org.apache.commons.lang3.StringUtils.equals(testPlan.getStatus(), TestPlanStatus.Prepare.name())
|
||||
|| org.apache.commons.lang3.StringUtils.equals(testPlan.getStatus(), TestPlanStatus.Completed.name())) {
|
||||
testPlan.setStatus(TestPlanStatus.Underway.name());
|
||||
testPlan.setActualStartTime(System.currentTimeMillis()); // 将状态更新为进行中时,开始时间也要更新
|
||||
testPlan.setActualEndTime(null);
|
||||
testPlanMapper.updateByPrimaryKey(testPlan);
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
package io.metersphere.track.service;
|
||||
|
||||
import io.metersphere.api.dto.DeleteAPIReportRequest;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||
import io.metersphere.api.dto.automation.ApiScenarioRequest;
|
||||
import io.metersphere.api.dto.automation.RunScenarioRequest;
|
||||
import io.metersphere.api.dto.automation.TestPlanScenarioRequest;
|
||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||
import io.metersphere.api.service.ApiAutomationService;
|
||||
import io.metersphere.api.service.ApiScenarioReportService;
|
||||
import io.metersphere.base.domain.TestPlanApiCase;
|
||||
import io.metersphere.base.domain.TestPlanApiCaseExample;
|
||||
import io.metersphere.base.domain.TestPlanApiScenario;
|
||||
import io.metersphere.base.domain.TestPlanApiScenarioExample;
|
||||
import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.utils.ServiceUtils;
|
||||
import io.metersphere.track.dto.RelevanceScenarioRequest;
|
||||
import io.metersphere.track.request.testcase.TestPlanApiCaseBatchRequest;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -42,20 +41,37 @@ public class TestPlanScenarioCaseService {
|
|||
request.setProjectId(null);
|
||||
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
|
||||
List<ApiScenarioDTO> apiTestCases = extTestPlanScenarioCaseMapper.list(request);
|
||||
setApiScenarioProjectIds(apiTestCases);
|
||||
if (CollectionUtils.isEmpty(apiTestCases)) {
|
||||
return apiTestCases;
|
||||
}
|
||||
return apiTestCases;
|
||||
}
|
||||
|
||||
private void setApiScenarioProjectIds(List<ApiScenarioDTO> list) {
|
||||
// 如果场景步骤涉及多项目,则把涉及到的项目ID保存在projectIds属性
|
||||
list.forEach(data -> {
|
||||
String definition = data.getScenarioDefinition();
|
||||
RunDefinitionRequest d = JSON.parseObject(definition, RunDefinitionRequest.class);
|
||||
Map<String, String> map = d.getEnvironmentMap();
|
||||
List<String> idList = new ArrayList<>();
|
||||
if (map != null) {
|
||||
Set<String> set = d.getEnvironmentMap().keySet();
|
||||
idList = new ArrayList<>(set);
|
||||
} else {
|
||||
if (org.apache.commons.lang3.StringUtils.isNotBlank(d.getEnvironmentId())) {
|
||||
idList.add(d.getEnvironmentId());
|
||||
}
|
||||
}
|
||||
data.setProjectIds(idList);
|
||||
});
|
||||
}
|
||||
|
||||
public List<ApiScenarioDTO> relevanceList(ApiScenarioRequest request) {
|
||||
// List<String> ids = apiAutomationService.selectIdsNotExistsInPlan(request.getProjectId(), request.getPlanId());
|
||||
// if (CollectionUtils.isEmpty(ids)) {
|
||||
// return new ArrayList<>();
|
||||
// }
|
||||
// request.setIds(ids);
|
||||
request.setNotInTestPlan(true);
|
||||
return apiAutomationService.list(request);
|
||||
List<ApiScenarioDTO> list = apiAutomationService.list(request);
|
||||
setApiScenarioProjectIds(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
public int delete(String id) {
|
||||
|
@ -137,4 +153,28 @@ public class TestPlanScenarioCaseService {
|
|||
example.createCriteria().andApiScenarioIdEqualTo(id);
|
||||
testPlanApiScenarioMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
public void batchUpdateEnv(RelevanceScenarioRequest request) {
|
||||
Map<String, String> envMap = request.getEnvMap();
|
||||
Map<String, List<String>> mapping = request.getMapping();
|
||||
Set<String> set = mapping.keySet();
|
||||
if (set.isEmpty()) { return; }
|
||||
set.forEach(id -> {
|
||||
Map<String, String> newEnvMap = new HashMap<>(16);
|
||||
if (envMap != null && !envMap.isEmpty()) {
|
||||
List<String> list = mapping.get(id);
|
||||
list.forEach(l -> {
|
||||
newEnvMap.put(l, envMap.get(l));
|
||||
});
|
||||
}
|
||||
if (!newEnvMap.isEmpty()) {
|
||||
TestPlanApiScenario scenario = new TestPlanApiScenario();
|
||||
scenario.setId(id);
|
||||
scenario.setEnvironment(JSON.toJSONString(newEnvMap));
|
||||
testPlanApiScenarioMapper.updateByPrimaryKeySelective(scenario);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,8 +159,8 @@ public class TestPlanService {
|
|||
public int editTestPlan(TestPlanDTO testPlan) {
|
||||
checkTestPlanExist(testPlan);
|
||||
TestPlan res = testPlanMapper.selectByPrimaryKey(testPlan.getId()); // 先查一次库
|
||||
testPlan.setUpdateTime(System.currentTimeMillis());
|
||||
if (!res.getStatus().equals(testPlan.getStatus())) { // 若有改变才更新时间
|
||||
testPlan.setUpdateTime(System.currentTimeMillis());
|
||||
if (TestPlanStatus.Underway.name().equals(testPlan.getStatus())) {
|
||||
if (res.getStatus().equals(TestPlanStatus.Prepare.name())) {
|
||||
testPlan.setActualStartTime(System.currentTimeMillis());
|
||||
|
@ -183,7 +183,13 @@ public class TestPlanService {
|
|||
List<String> userIds = new ArrayList<>();
|
||||
userIds.add(testPlan.getPrincipal());
|
||||
AddTestPlanRequest testPlans = new AddTestPlanRequest();
|
||||
int i = testPlanMapper.updateByPrimaryKeySelective(testPlan); // 更新
|
||||
int i;
|
||||
if(testPlan.getName() == null) {// 若是点击该测试计划,则仅更新了updateTime,其它字段全为null,使用updateByPrimaryKeySelective
|
||||
i = testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||
}
|
||||
else { // 有修改字段的调用,为保证将某些时间置null的情况,使用updateByPrimaryKey
|
||||
i = testPlanMapper.updateByPrimaryKey(testPlan); // 更新
|
||||
}
|
||||
if (!StringUtils.isBlank(testPlan.getStatus())) {
|
||||
BeanUtils.copyBean(testPlans, getTestPlan(testPlan.getId()));
|
||||
String context = getTestPlanContext(testPlans, NoticeConstants.Event.UPDATE);
|
||||
|
@ -412,6 +418,8 @@ public class TestPlanService {
|
|||
if (StringUtils.equals(testPlan.getStatus(), TestPlanStatus.Prepare.name())
|
||||
|| StringUtils.equals(testPlan.getStatus(), TestPlanStatus.Completed.name())) {
|
||||
testPlan.setStatus(TestPlanStatus.Underway.name());
|
||||
testPlan.setActualStartTime(System.currentTimeMillis()); // 将状态更新为进行中时,开始时间也要更新
|
||||
testPlan.setActualEndTime(null);
|
||||
testPlanMapper.updateByPrimaryKey(testPlan);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,19 +16,16 @@ ALTER TABLE test_resource_pool ADD gc_algo VARCHAR(200) NULL;
|
|||
|
||||
-- create tale api_document_share
|
||||
CREATE TABLE IF NOT EXISTS `api_document_share` (
|
||||
`id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Api Document Share Info ID',
|
||||
`create_time` BIGINT ( 13 ) NOT NULL COMMENT 'Create timestamp',
|
||||
`create_user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
|
||||
`update_time` BIGINT(13) NOT NULL COMMENT 'last visit timestamp',
|
||||
`share_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'single or batch',
|
||||
`share_api_id` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'APiDefinition.id (JSONArray format. Order by TreeSet)',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `share_type` (`share_type`) USING BTREE,
|
||||
INDEX `share_api_id` (`share_api_id`(125)) USING BTREE
|
||||
) ENGINE = InnoDB
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci
|
||||
ROW_FORMAT = Dynamic;
|
||||
`id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Api Document Share Info ID',
|
||||
`create_time` BIGINT ( 13 ) NOT NULL COMMENT 'Create timestamp',
|
||||
`create_user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
|
||||
`update_time` BIGINT ( 13 ) NOT NULL COMMENT 'last visit timestamp',
|
||||
`share_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'single or batch',
|
||||
`share_api_id` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'APiDefinition.id (JSONArray format. Order by TreeSet)',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `share_type`(`share_type`) USING BTREE,
|
||||
INDEX `share_api_id`(`share_api_id`(125)) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- test_case_review add coloumn
|
||||
ALTER TABLE test_case_review
|
||||
|
@ -47,5 +44,8 @@ alter table test_case
|
|||
-- test_case_review add column
|
||||
ALTER TABLE test_case_review ADD tags VARCHAR(2000) NULL;
|
||||
|
||||
-- alter test_plan_api_scenario
|
||||
alter table test_plan_api_scenario change environment_id environment longtext null comment 'Relevance environment';
|
||||
|
||||
-- file add sort column
|
||||
alter table file_metadata add sort int default 0;
|
|
@ -34,7 +34,7 @@ edit_load_test_not_found=无法编辑测试,未找到测试:
|
|||
run_load_test_not_found=无法运行测试,未找到测试:
|
||||
run_load_test_file_not_found=无法运行测试,无法获取测试文件元信息,测试ID:
|
||||
run_load_test_file_content_not_found=无法运行测试,无法获取测试文件内容,测试ID:
|
||||
run_load_test_file_init_error=无法运行测试,请检查当前站点配置
|
||||
run_load_test_file_init_error=无法运行测试,请前往 [系统设置-系统-系统参数设置] 检查当前站点配置,详情见https://metersphere.io/docs/faq/load_test/#url
|
||||
load_test_is_running=测试正在运行, 请等待
|
||||
load_test_kafka_invalid=Kafka 不可用,请检查配置
|
||||
cannot_edit_load_test_running=不能修改正在运行的测试
|
||||
|
|
|
@ -662,7 +662,7 @@
|
|||
}
|
||||
const index = hashTree.findIndex(d => d.resourceId === row.resourceId);
|
||||
if (index != -1) {
|
||||
hashTree.splice(index, 0, obj);
|
||||
hashTree.splice(index+1, 0, obj);
|
||||
} else {
|
||||
hashTree.push(obj);
|
||||
}
|
||||
|
|
|
@ -1,30 +1,68 @@
|
|||
<template>
|
||||
<el-form :model="editData" label-position="right" label-width="80px" size="small" ref="form">
|
||||
<el-form-item :label="$t('api_test.variable_name')" prop="name">
|
||||
<el-input v-model="editData.name" :placeholder="$t('api_test.variable_name')" ref="nameInput"></el-input>
|
||||
</el-form-item>
|
||||
<div>
|
||||
<el-form :model="editData" label-position="right" label-width="80px" size="small" ref="form">
|
||||
<el-form-item :label="$t('api_test.variable_name')" prop="name">
|
||||
<el-input v-model="editData.name" :placeholder="$t('api_test.variable_name')" ref="nameInput"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('commons.description')" prop="description">
|
||||
<el-input class="ms-http-textarea"
|
||||
v-model="editData.description"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 10}"
|
||||
:rows="2" size="small"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.description')" prop="description">
|
||||
<el-input class="ms-http-textarea"
|
||||
v-model="editData.description"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 10}"
|
||||
:rows="2" size="small"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.value')" prop="value">
|
||||
<el-input v-model="editData.value" :placeholder="$t('api_test.value')"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form-item :label="$t('api_test.value')" prop="value">
|
||||
<el-col class="item">
|
||||
<el-autocomplete
|
||||
size="small"
|
||||
:placeholder="$t('api_test.value')"
|
||||
style="width: 100%;"
|
||||
v-model="editData.value"
|
||||
value-key="name"
|
||||
:fetch-suggestions="funcSearch"
|
||||
highlight-first-item>
|
||||
<i slot="suffix" class="el-input__icon el-icon-edit pointer" @click="advanced"></i>
|
||||
</el-autocomplete>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<ms-api-variable-advance ref="variableAdvance"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {JMETER_FUNC, MOCKJS_FUNC} from "@/common/js/constants";
|
||||
import MsApiVariableAdvance from "../../../test/components/ApiVariableAdvance";
|
||||
|
||||
export default {
|
||||
name: "MsEditConstant",
|
||||
components: {},
|
||||
components: {MsApiVariableAdvance},
|
||||
props: {
|
||||
editData: {},
|
||||
},
|
||||
methods: {
|
||||
advanced() {
|
||||
this.$refs.variableAdvance.open();
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return (variable) => {
|
||||
return (variable.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
||||
};
|
||||
},
|
||||
funcFilter(queryString) {
|
||||
return (func) => {
|
||||
return (func.name.toLowerCase().indexOf(queryString.toLowerCase()) > -1);
|
||||
};
|
||||
},
|
||||
funcSearch(queryString, cb) {
|
||||
let funcs = MOCKJS_FUNC.concat(JMETER_FUNC);
|
||||
let results = queryString ? funcs.filter(this.funcFilter(queryString)) : funcs;
|
||||
// 调用 callback 返回建议列表的数据
|
||||
cb(results);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.nameInput.focus();
|
||||
|
|
|
@ -124,18 +124,22 @@ export default {
|
|||
},
|
||||
scheduleChange(){
|
||||
let flag = this.schedule.enable;
|
||||
this.$confirm(this.$t('api_test.home_page.running_task_list.confirm.close_title'), this.$t('commons.prompt'), {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let param = {};
|
||||
param.taskID = this.schedule.id;
|
||||
param.enable = flag;
|
||||
let param = {};
|
||||
param.taskID = this.schedule.id;
|
||||
param.enable = flag;
|
||||
if(flag == false) {
|
||||
this.$confirm(this.$t('api_test.home_page.running_task_list.confirm.close_title'), this.$t('commons.prompt'), {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.updateTask(param);
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.updateTask(param);
|
||||
}).catch(() => {
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
updateTask(param){
|
||||
this.result = this.$post('/api/schedule/updateEnableByPrimyKey', param, response => {
|
||||
|
|
|
@ -3,6 +3,15 @@
|
|||
<span class="kv-description" v-if="description">
|
||||
{{ description }}
|
||||
</span>
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
全选/反选<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="selectAll">全选</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="invertSelect">反选</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<div class="kv-row item" v-for="(item, index) in items" :key="index">
|
||||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||
<el-col class="kv-checkbox" v-if="isShowEnable">
|
||||
|
@ -19,7 +28,7 @@
|
|||
<el-input v-if="!suggestions" :disabled="isReadOnly" v-model="item.name" size="small" maxlength="200"
|
||||
@change="change"
|
||||
:placeholder="keyText" show-word-limit/>
|
||||
<el-autocomplete :disabled="isReadOnly" :maxlength="200" v-if="suggestions" v-model="item.name" size="small"
|
||||
<el-autocomplete :disabled="isReadOnly" :maxlength="400" v-if="suggestions" v-model="item.name" size="small"
|
||||
:fetch-suggestions="querySearch" @change="change" :placeholder="keyText"
|
||||
show-word-limit/>
|
||||
|
||||
|
@ -138,6 +147,16 @@
|
|||
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
||||
};
|
||||
},
|
||||
selectAll() {
|
||||
this.items.forEach(item => {
|
||||
item.enable = true;
|
||||
});
|
||||
},
|
||||
invertSelect() {
|
||||
this.items.forEach(item => {
|
||||
item.enable = !item.enable;
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.items.length === 0 || this.items[this.items.length - 1].name) {
|
||||
|
|
|
@ -15,8 +15,15 @@
|
|||
:placeholder="$t('api_test.variable_name')" show-word-limit/>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input :disabled="isReadOnly" v-model="item.value" size="small" @change="change"
|
||||
:placeholder="$t('api_test.value')" show-word-limit/>
|
||||
<el-autocomplete
|
||||
size="small"
|
||||
v-model="item.value"
|
||||
:fetch-suggestions="funcSearch"
|
||||
:placeholder="$t('api_test.value')"
|
||||
value-key="name"
|
||||
highlight-first-item>
|
||||
<i slot="suffix" class="el-input__icon el-icon-edit pointer" @click="advanced"></i>
|
||||
</el-autocomplete>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input v-model="item.description" size="small" maxlength="200"
|
||||
|
@ -33,16 +40,19 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-api-variable-advance ref="variableAdvance"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {KeyValue} from "../model/ApiTestModel";
|
||||
import MsApiVariableInput from "./ApiVariableInput";
|
||||
import {JMETER_FUNC, MOCKJS_FUNC} from "@/common/js/constants";
|
||||
import MsApiVariableAdvance from "../../test/components/ApiVariableAdvance";
|
||||
|
||||
export default {
|
||||
name: "MsApiScenarioVariables",
|
||||
components: {MsApiVariableInput},
|
||||
components: {MsApiVariableInput, MsApiVariableAdvance},
|
||||
props: {
|
||||
description: String,
|
||||
items: Array,
|
||||
|
@ -94,7 +104,26 @@
|
|||
},
|
||||
isDisable: function (index) {
|
||||
return this.items.length - 1 === index;
|
||||
}
|
||||
},
|
||||
advanced() {
|
||||
this.$refs.variableAdvance.open();
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return (variable) => {
|
||||
return (variable.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
||||
};
|
||||
},
|
||||
funcFilter(queryString) {
|
||||
return (func) => {
|
||||
return (func.name.toLowerCase().indexOf(queryString.toLowerCase()) > -1);
|
||||
};
|
||||
},
|
||||
funcSearch(queryString, cb) {
|
||||
let funcs = MOCKJS_FUNC.concat(JMETER_FUNC);
|
||||
let results = queryString ? funcs.filter(this.funcFilter(queryString)) : funcs;
|
||||
// 调用 callback 返回建议列表的数据
|
||||
cb(results);
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
|
|
|
@ -3,7 +3,15 @@
|
|||
<span class="kv-description" v-if="description">
|
||||
{{ description }}
|
||||
</span>
|
||||
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
全选/反选<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="selectAll">全选</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="invertSelect">反选</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<div class="item kv-row" v-for="(item, index) in parameters" :key="index">
|
||||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||
<el-col class="kv-checkbox" v-if="isShowEnable">
|
||||
|
@ -220,6 +228,16 @@
|
|||
item.contentType = 'text/plain';
|
||||
}
|
||||
},
|
||||
selectAll() {
|
||||
this.parameters.forEach(item => {
|
||||
item.enable = true;
|
||||
});
|
||||
},
|
||||
invertSelect() {
|
||||
this.parameters.forEach(item => {
|
||||
item.enable = !item.enable;
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.parameters.length === 0 || this.parameters[this.parameters.length - 1].name) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="variable-input">
|
||||
<el-input class="el-input__inner_pd" :disabled="isReadOnly" :value="value" v-bind="$attrs" :size="size" @change="change" @input="input"/>
|
||||
<el-input :disabled="isReadOnly" :value="value" v-bind="$attrs" :size="size" @change="change" @input="input"/>
|
||||
<div :class="{'hidden': !showVariable}" class="variable-combine" v-if="value">
|
||||
<div v-if="showCopy" class="variable">{{variable}}</div>
|
||||
<el-tooltip v-if="showCopy" :content="$t('api_test.copied')" manual v-model="visible" placement="top" :visible-arrow="false">
|
||||
|
|
|
@ -473,9 +473,16 @@ export default {
|
|||
},
|
||||
handleDelete(apiCase) {
|
||||
// if (this.trashEnable) {
|
||||
this.$get('/api/testcase/delete/' + apiCase.id, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.initTable();
|
||||
this.$alert(this.$t('api_test.definition.request.delete_confirm') + ' ' + apiCase.name + " ?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.$get('/api/testcase/delete/' + apiCase.id, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.initTable();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
},
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<el-dialog :title="$t('api_test.request.parameters_advance')"
|
||||
:visible.sync="itemValueVisible"
|
||||
class="advanced-item-value"
|
||||
:append-to-body="true"
|
||||
width="70%">
|
||||
<el-tabs tab-position="top" style="height: 50vh;" @tab-click="selectTab">
|
||||
<el-tab-pane :label="$t('api_test.request.parameters_advance_mock')">
|
||||
|
|
|
@ -112,6 +112,13 @@
|
|||
this.projectIds.add(row.projectId)
|
||||
})
|
||||
},
|
||||
setScenarioSelectRows(rows) {
|
||||
this.selectRows = rows;
|
||||
this.projectIds.clear();
|
||||
this.selectRows.forEach(row => {
|
||||
row.projectIds.forEach(id => this.projectIds.add(id));
|
||||
})
|
||||
},
|
||||
handleClose() {
|
||||
this.form = {};
|
||||
this.options = [];
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
<div>
|
||||
<el-card class="table-card" v-loading="result.loading">
|
||||
|
||||
<env-popover :env-map="projectEnvMap" :project-ids="projectIds" @setProjectEnvMap="setProjectEnvMap"
|
||||
:project-list="projectList" ref="envPopover" class="env-popover"/>
|
||||
|
||||
<el-table ref="scenarioTable" border :data="tableData" class="adjust-table" @select-all="handleSelectAll" @select="handleSelect">
|
||||
<el-table-column type="selection"/>
|
||||
|
||||
|
@ -56,10 +59,12 @@
|
|||
import MsTestPlanList from "../../../../../api/automation/scenario/testplan/TestPlanList";
|
||||
import TestPlanScenarioListHeader from "./TestPlanScenarioListHeader";
|
||||
import {_handleSelect, _handleSelectAll} from "../../../../../../../common/js/tableUtils";
|
||||
import EnvPopover from "@/business/components/api/automation/scenario/EnvPopover";
|
||||
|
||||
export default {
|
||||
name: "RelevanceScenarioList",
|
||||
components: {
|
||||
EnvPopover,
|
||||
TestPlanScenarioListHeader,
|
||||
MsTablePagination, MsTableMoreBtn, ShowMoreBtn, MsTableHeader, MsTag, MsApiReportDetail, MsTestPlanList},
|
||||
props: {
|
||||
|
@ -84,7 +89,10 @@
|
|||
total: 0,
|
||||
reportId: "",
|
||||
infoDb: false,
|
||||
selectRows: new Set()
|
||||
selectRows: new Set(),
|
||||
projectEnvMap: new Map(),
|
||||
projectList: [],
|
||||
projectIds: new Set(),
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -95,8 +103,13 @@
|
|||
this.search();
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getWsProjects();
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
this.projectEnvMap.clear();
|
||||
this.projectIds.clear();
|
||||
if (!this.projectId) {
|
||||
return;
|
||||
}
|
||||
|
@ -129,10 +142,31 @@
|
|||
},
|
||||
handleSelectAll(selection) {
|
||||
_handleSelectAll(this, selection, this.tableData, this.selectRows);
|
||||
this.initProjectIds();
|
||||
},
|
||||
handleSelect(selection, row) {
|
||||
_handleSelect(this, selection, row, this.selectRows);
|
||||
this.initProjectIds();
|
||||
},
|
||||
setProjectEnvMap(projectEnvMap) {
|
||||
this.projectEnvMap = projectEnvMap;
|
||||
},
|
||||
getWsProjects() {
|
||||
this.$get("/project/listAll", res => {
|
||||
this.projectList = res.data;
|
||||
})
|
||||
},
|
||||
initProjectIds() {
|
||||
this.projectIds.clear();
|
||||
this.selectRows.forEach(row => {
|
||||
row.projectIds.forEach(id => {
|
||||
this.projectIds.add(id);
|
||||
})
|
||||
})
|
||||
},
|
||||
checkEnv() {
|
||||
return this.$refs.envPopover.checkEnv();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -141,4 +175,9 @@
|
|||
/deep/ .el-drawer__header {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.env-popover {
|
||||
float: right;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
import TestCaseRelevanceBase from "../base/TestCaseRelevanceBase";
|
||||
import MsApiModule from "../../../../../api/definition/components/module/ApiModule";
|
||||
import {getCurrentProjectID} from "../../../../../../../common/js/utils";
|
||||
import {getCurrentProjectID, strMapToObj} from "../../../../../../../common/js/utils";
|
||||
import ApiList from "../../../../../api/definition/components/list/ApiList";
|
||||
import ApiCaseSimpleList from "../../../../../api/definition/components/list/ApiCaseSimpleList";
|
||||
import MsApiScenarioList from "../../../../../api/automation/scenario/ApiScenarioList";
|
||||
|
@ -98,13 +98,21 @@
|
|||
},
|
||||
|
||||
saveCaseRelevance() {
|
||||
const sign = this.$refs.apiScenarioList.checkEnv();
|
||||
if (!sign) {
|
||||
return false;
|
||||
}
|
||||
let param = {};
|
||||
let url = '';
|
||||
let selectIds = [];
|
||||
url = '/api/automation/relevance';
|
||||
selectIds = Array.from(this.$refs.apiScenarioList.selectRows).map(row => row.id);
|
||||
let url = '/api/automation/relevance';
|
||||
let rows = this.$refs.apiScenarioList.selectRows;
|
||||
const envMap = this.$refs.apiScenarioList.projectEnvMap;
|
||||
let map = new Map();
|
||||
rows.forEach(row => {
|
||||
map.set(row.id, row.projectIds);
|
||||
})
|
||||
param.planId = this.planId;
|
||||
param.selectIds = selectIds;
|
||||
param.mapping = strMapToObj(map);
|
||||
param.envMap = strMapToObj(envMap);
|
||||
|
||||
this.result = this.$post(url, param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
<el-table-column v-if="item.id == 'tagNames'" prop="tagNames" :label="$t('api_test.automation.tag')"
|
||||
width="200px" :key="index">
|
||||
<template v-slot:default="scope">
|
||||
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain" :content="itemName" style="margin-left: 5px"/>
|
||||
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain"
|
||||
:content="itemName" style="margin-left: 5px"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="item.id == 'userId'" prop="userId" :label="$t('api_test.automation.creator')"
|
||||
|
@ -90,6 +91,10 @@
|
|||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 批量编辑 -->
|
||||
<batch-edit :dialog-title="$t('test_track.case.batch_edit_case')" :type-arr="typeArr" :value-arr="valueArr"
|
||||
:select-row="selectRows" ref="batchEdit" @batchEdit="batchEdit"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -98,7 +103,7 @@ import MsTableHeader from "@/business/components/common/components/MsTableHeader
|
|||
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import ShowMoreBtn from "@/business/components/track/case/components/ShowMoreBtn";
|
||||
import MsTag from "../../../../../common/components/MsTag";
|
||||
import {getUUID, getCurrentProjectID, getCurrentUser} from "@/common/js/utils";
|
||||
import {getUUID, getCurrentProjectID, getCurrentUser, strMapToObj} from "@/common/js/utils";
|
||||
import MsApiReportDetail from "../../../../../api/automation/report/ApiReportDetail";
|
||||
import MsTableMoreBtn from "../../../../../api/automation/scenario/TableMoreBtn";
|
||||
import MsScenarioExtendButtons from "@/business/components/api/automation/scenario/ScenarioExtendBtns";
|
||||
|
@ -110,6 +115,7 @@ import HeaderCustom from "@/business/components/common/head/HeaderCustom";
|
|||
import {TEST_CASE_LIST, TEST_PLAN_SCENARIO_CASE} from "@/common/js/constants";
|
||||
import {Test_Plan_Scenario_Case, Track_Test_Case} from "@/business/components/common/model/JsonData";
|
||||
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
|
||||
import BatchEdit from "@/business/components/track/case/components/BatchEdit";
|
||||
|
||||
export default {
|
||||
name: "MsTestPlanApiScenarioList",
|
||||
|
@ -125,7 +131,8 @@ export default {
|
|||
MsTag,
|
||||
MsApiReportDetail,
|
||||
MsScenarioExtendButtons,
|
||||
MsTestPlanList
|
||||
MsTestPlanList,
|
||||
BatchEdit
|
||||
},
|
||||
props: {
|
||||
referenced: {
|
||||
|
@ -162,9 +169,16 @@ export default {
|
|||
},
|
||||
{
|
||||
name: this.$t('api_test.automation.batch_execute'), handleClick: this.handleBatchExecute
|
||||
}
|
||||
},
|
||||
{name: this.$t('test_track.case.batch_edit_case'), handleClick: this.handleBatchEdit}
|
||||
],
|
||||
selectRows: new Set()
|
||||
selectRows: new Set(),
|
||||
typeArr: [
|
||||
{id: 'projectEnv', name: this.$t('api_test.definition.request.run_env')},
|
||||
],
|
||||
valueArr: {
|
||||
projectEnv: []
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -284,7 +298,24 @@ export default {
|
|||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
handleBatchEdit() {
|
||||
this.$refs.batchEdit.open(this.selectRows.size);
|
||||
this.$refs.batchEdit.setScenarioSelectRows(this.selectRows);
|
||||
},
|
||||
batchEdit(form) {
|
||||
let param = {};
|
||||
let map = new Map();
|
||||
this.selectRows.forEach(row => {
|
||||
map.set(row.id, row.projectIds);
|
||||
})
|
||||
param.mapping = strMapToObj(map);
|
||||
param.envMap = strMapToObj(form.projectEnvMap);
|
||||
this.$post('/test/plan/scenario/case/batch/update/env', param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.search();
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue